blob: 12bcc2a1c4b1a601f286f73844a4009cb01f102a [file] [log] [blame]
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#include <Ph.h>
#include <photon/Pg.h>
#include "SDL_endian.h"
#include "SDL_video.h"
#include "../SDL_pixels_c.h"
#include "SDL_ph_video.h"
#include "SDL_ph_image_c.h"
#include "SDL_ph_modes_c.h"
#include "SDL_ph_gl.h"
int
ph_SetupImage(_THIS, SDL_Surface * screen)
{
PgColor_t *palette = NULL;
int type = 0;
int bpp;
bpp = screen->format->BitsPerPixel;
/* Determine image type */
switch (bpp) {
case 8:
{
type = Pg_IMAGE_PALETTE_BYTE;
}
break;
case 15:
{
type = Pg_IMAGE_DIRECT_555;
}
break;
case 16:
{
type = Pg_IMAGE_DIRECT_565;
}
break;
case 24:
{
type = Pg_IMAGE_DIRECT_888;
}
break;
case 32:
{
type = Pg_IMAGE_DIRECT_8888;
}
break;
default:
{
SDL_SetError("ph_SetupImage(): unsupported bpp=%d !\n", bpp);
return -1;
}
break;
}
/* palette emulation code */
if ((bpp == 8) && (desktoppal == SDLPH_PAL_EMULATE)) {
/* creating image palette */
palette = SDL_malloc(_Pg_MAX_PALETTE * sizeof(PgColor_t));
if (palette == NULL) {
SDL_SetError
("ph_SetupImage(): can't allocate memory for palette !\n");
return -1;
}
PgGetPalette(palette);
/* using shared memory for speed (set last param to 1) */
if ((SDL_Image =
PhCreateImage(NULL, screen->w, screen->h, type, palette,
_Pg_MAX_PALETTE, 1)) == NULL) {
SDL_SetError
("ph_SetupImage(): PhCreateImage() failed for bpp=8 !\n");
SDL_free(palette);
return -1;
}
} else {
/* using shared memory for speed (set last param to 1) */
if ((SDL_Image =
PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0,
1)) == NULL) {
SDL_SetError
("ph_SetupImage(): PhCreateImage() failed for bpp=%d !\n",
bpp);
return -1;
}
}
screen->pixels = SDL_Image->image;
screen->pitch = SDL_Image->bpl;
this->UpdateRects = ph_NormalUpdate;
return 0;
}
int
ph_SetupOCImage(_THIS, SDL_Surface * screen)
{
int type = 0;
int bpp;
OCImage.flags = screen->flags;
bpp = screen->format->BitsPerPixel;
/* Determine image type */
switch (bpp) {
case 8:
{
type = Pg_IMAGE_PALETTE_BYTE;
}
break;
case 15:
{
type = Pg_IMAGE_DIRECT_555;
}
break;
case 16:
{
type = Pg_IMAGE_DIRECT_565;
}
break;
case 24:
{
type = Pg_IMAGE_DIRECT_888;
}
break;
case 32:
{
type = Pg_IMAGE_DIRECT_8888;
}
break;
default:
{
SDL_SetError("ph_SetupOCImage(): unsupported bpp=%d !\n", bpp);
return -1;
}
break;
}
/* Currently offscreen contexts with the same bit depth as display bpp only can be created */
OCImage.offscreen_context =
PdCreateOffscreenContext(0, screen->w, screen->h,
Pg_OSC_MEM_PAGE_ALIGN);
if (OCImage.offscreen_context == NULL) {
SDL_SetError
("ph_SetupOCImage(): PdCreateOffscreenContext() function failed !\n");
return -1;
}
screen->pitch = OCImage.offscreen_context->pitch;
OCImage.dc_ptr =
(unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context);
if (OCImage.dc_ptr == NULL) {
SDL_SetError
("ph_SetupOCImage(): PdGetOffscreenContextPtr function failed !\n");
PhDCRelease(OCImage.offscreen_context);
return -1;
}
OCImage.FrameData0 = OCImage.dc_ptr;
OCImage.CurrentFrameData = OCImage.FrameData0;
OCImage.current = 0;
PhDCSetCurrent(OCImage.offscreen_context);
screen->pixels = OCImage.CurrentFrameData;
this->UpdateRects = ph_OCUpdate;
return 0;
}
int
ph_SetupFullScreenImage(_THIS, SDL_Surface * screen)
{
OCImage.flags = screen->flags;
/* Begin direct and fullscreen mode */
if (!ph_EnterFullScreen(this, screen, PH_ENTER_DIRECTMODE)) {
return -1;
}
/* store palette for fullscreen */
if ((screen->format->BitsPerPixel == 8) && (desktopbpp != 8)) {
PgGetPalette(savedpal);
PgGetPalette(syspalph);
}
OCImage.offscreen_context =
PdCreateOffscreenContext(0, 0, 0,
Pg_OSC_MAIN_DISPLAY | Pg_OSC_MEM_PAGE_ALIGN
| Pg_OSC_CRTC_SAFE);
if (OCImage.offscreen_context == NULL) {
SDL_SetError
("ph_SetupFullScreenImage(): PdCreateOffscreenContext() function failed !\n");
return -1;
}
if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
OCImage.offscreen_backcontext =
PdDupOffscreenContext(OCImage.offscreen_context,
Pg_OSC_MEM_PAGE_ALIGN | Pg_OSC_CRTC_SAFE);
if (OCImage.offscreen_backcontext == NULL) {
SDL_SetError
("ph_SetupFullScreenImage(): PdCreateOffscreenContext(back) function failed !\n");
return -1;
}
}
OCImage.FrameData0 =
(unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context);
if (OCImage.FrameData0 == NULL) {
SDL_SetError
("ph_SetupFullScreenImage(): PdGetOffscreenContextPtr() function failed !\n");
ph_DestroyImage(this, screen);
return -1;
}
if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
OCImage.FrameData1 =
(unsigned char *) PdGetOffscreenContextPtr(OCImage.
offscreen_backcontext);
if (OCImage.FrameData1 == NULL) {
SDL_SetError
("ph_SetupFullScreenImage(back): PdGetOffscreenContextPtr() function failed !\n");
ph_DestroyImage(this, screen);
return -1;
}
}
/* wait for the hardware */
PgFlush();
PgWaitHWIdle();
if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
OCImage.current = 0;
PhDCSetCurrent(OCImage.offscreen_context);
screen->pitch = OCImage.offscreen_context->pitch;
screen->pixels = OCImage.FrameData0;
/* emulate 640x400 videomode */
if (videomode_emulatemode == 1) {
int i;
for (i = 0; i < 40; i++) {
SDL_memset(screen->pixels + screen->pitch * i, 0x00,
screen->pitch);
}
for (i = 440; i < 480; i++) {
SDL_memset(screen->pixels + screen->pitch * i, 0x00,
screen->pitch);
}
screen->pixels += screen->pitch * 40;
}
PgSwapDisplay(OCImage.offscreen_backcontext, 0);
} else {
OCImage.current = 0;
PhDCSetCurrent(OCImage.offscreen_context);
screen->pitch = OCImage.offscreen_context->pitch;
screen->pixels = OCImage.FrameData0;
/* emulate 640x400 videomode */
if (videomode_emulatemode == 1) {
int i;
for (i = 0; i < 40; i++) {
SDL_memset(screen->pixels + screen->pitch * i, 0x00,
screen->pitch);
}
for (i = 440; i < 480; i++) {
SDL_memset(screen->pixels + screen->pitch * i, 0x00,
screen->pitch);
}
screen->pixels += screen->pitch * 40;
}
}
this->UpdateRects = ph_OCDCUpdate;
/* wait for the hardware */
PgFlush();
PgWaitHWIdle();
return 0;
}
#if SDL_VIDEO_OPENGL
int
ph_SetupOpenGLImage(_THIS, SDL_Surface * screen)
{
this->UpdateRects = ph_OpenGLUpdate;
screen->pixels = NULL;
screen->pitch = NULL;
#if (_NTO_VERSION >= 630)
if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
if (!ph_EnterFullScreen(this, screen, PH_IGNORE_DIRECTMODE)) {
screen->flags &= ~SDL_FULLSCREEN;
return -1;
}
}
#endif /* 6.3.0 */
if (ph_SetupOpenGLContext
(this, screen->w, screen->h, screen->format->BitsPerPixel,
screen->flags) != 0) {
screen->flags &= ~SDL_INTERNALOPENGL;
return -1;
}
return 0;
}
#endif /* SDL_VIDEO_OPENGL */
void
ph_DestroyImage(_THIS, SDL_Surface * screen)
{
#if SDL_VIDEO_OPENGL
if (screen->flags & SDL_INTERNALOPENGL) {
if (oglctx) {
#if (_NTO_VERSION < 630)
PhDCSetCurrent(NULL);
PhDCRelease(oglctx);
#else
qnxgl_context_destroy(oglctx);
qnxgl_buffers_destroy(oglbuffers);
qnxgl_finish();
#endif /* 6.3.0 */
oglctx = NULL;
oglbuffers = NULL;
oglflags = 0;
oglbpp = 0;
}
#if (_NTO_VERSION >= 630)
if (currently_fullscreen) {
ph_LeaveFullScreen(this);
}
#endif /* 6.3.0 */
return;
}
#endif /* SDL_VIDEO_OPENGL */
if (currently_fullscreen) {
/* if we right now in 8bpp fullscreen we must release palette */
if ((screen->format->BitsPerPixel == 8) && (desktopbpp != 8)) {
PgSetPalette(syspalph, 0, -1, 0, 0, 0);
PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE,
Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
PgFlush();
}
ph_LeaveFullScreen(this);
}
if (OCImage.offscreen_context != NULL) {
PhDCRelease(OCImage.offscreen_context);
OCImage.offscreen_context = NULL;
OCImage.FrameData0 = NULL;
}
if (OCImage.offscreen_backcontext != NULL) {
PhDCRelease(OCImage.offscreen_backcontext);
OCImage.offscreen_backcontext = NULL;
OCImage.FrameData1 = NULL;
}
OCImage.CurrentFrameData = NULL;
if (SDL_Image) {
/* if palette allocated, free it */
if (SDL_Image->palette) {
SDL_free(SDL_Image->palette);
}
PgShmemDestroy(SDL_Image->image);
SDL_free(SDL_Image);
}
/* Must be zeroed everytime */
SDL_Image = NULL;
if (screen) {
screen->pixels = NULL;
}
}
int
ph_UpdateHWInfo(_THIS)
{
PgVideoModeInfo_t vmode;
PgHWCaps_t hwcaps;
/* Update video ram amount */
if (PgGetGraphicsHWCaps(&hwcaps) < 0) {
SDL_SetError
("ph_UpdateHWInfo(): GetGraphicsHWCaps() function failed !\n");
return -1;
}
this->info.video_mem = hwcaps.currently_available_video_ram / 1024;
/* obtain current mode capabilities */
if (PgGetVideoModeInfo(hwcaps.current_video_mode, &vmode) < 0) {
SDL_SetError
("ph_UpdateHWInfo(): GetVideoModeInfo() function failed !\n");
return -1;
}
if ((vmode.mode_capabilities1 & PgVM_MODE_CAP1_OFFSCREEN) ==
PgVM_MODE_CAP1_OFFSCREEN) {
/* this is a special test for drivers which tries to lie about offscreen capability */
if (hwcaps.currently_available_video_ram != 0) {
this->info.hw_available = 1;
} else {
this->info.hw_available = 0;
}
} else {
this->info.hw_available = 0;
}
if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_RECTANGLE) ==
PgVM_MODE_CAP2_RECTANGLE) {
this->info.blit_fill = 1;
} else {
this->info.blit_fill = 0;
}
if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_BITBLT) ==
PgVM_MODE_CAP2_BITBLT) {
this->info.blit_hw = 1;
} else {
this->info.blit_hw = 0;
}
if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_ALPHA_BLEND) ==
PgVM_MODE_CAP2_ALPHA_BLEND) {
this->info.blit_hw_A = 1;
} else {
this->info.blit_hw_A = 0;
}
if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_CHROMA) ==
PgVM_MODE_CAP2_CHROMA) {
this->info.blit_hw_CC = 1;
} else {
this->info.blit_hw_CC = 0;
}
return 0;
}
int
ph_SetupUpdateFunction(_THIS, SDL_Surface * screen, Uint32 flags)
{
int setupresult = -1;
ph_DestroyImage(this, screen);
#if SDL_VIDEO_OPENGL
if (flags & SDL_INTERNALOPENGL) {
setupresult = ph_SetupOpenGLImage(this, screen);
} else {
#endif
if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
setupresult = ph_SetupFullScreenImage(this, screen);
} else {
if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
setupresult = ph_SetupOCImage(this, screen);
} else {
setupresult = ph_SetupImage(this, screen);
}
}
#if SDL_VIDEO_OPENGL
}
#endif
if (setupresult != -1) {
ph_UpdateHWInfo(this);
}
return setupresult;
}
int
ph_AllocHWSurface(_THIS, SDL_Surface * surface)
{
PgHWCaps_t hwcaps;
if (surface->hwdata != NULL) {
SDL_SetError("ph_AllocHWSurface(): hwdata already exists!\n");
return -1;
}
surface->hwdata = SDL_malloc(sizeof(struct private_hwdata));
SDL_memset(surface->hwdata, 0x00, sizeof(struct private_hwdata));
surface->hwdata->offscreenctx =
PdCreateOffscreenContext(0, surface->w, surface->h,
Pg_OSC_MEM_PAGE_ALIGN);
if (surface->hwdata->offscreenctx == NULL) {
SDL_SetError
("ph_AllocHWSurface(): PdCreateOffscreenContext() function failed !\n");
return -1;
}
surface->pixels = PdGetOffscreenContextPtr(surface->hwdata->offscreenctx);
if (surface->pixels == NULL) {
PhDCRelease(surface->hwdata->offscreenctx);
SDL_SetError
("ph_AllocHWSurface(): PdGetOffscreenContextPtr() function failed !\n");
return -1;
}
surface->pitch = surface->hwdata->offscreenctx->pitch;
surface->flags |= SDL_HWSURFACE;
surface->flags |= SDL_PREALLOC;
#if 0 /* FIXME */
/* create simple offscreen lock */
surface->hwdata->crlockparam.flags = 0;
if (PdCreateOffscreenLock
(surface->hwdata->offscreenctx, &surface->hwdata->crlockparam) != EOK)
{
PhDCRelease(surface->hwdata->offscreenctx);
SDL_SetError("ph_AllocHWSurface(): Can't create offscreen lock !\n");
return -1;
}
#endif /* 0 */
/* Update video ram amount */
if (PgGetGraphicsHWCaps(&hwcaps) < 0) {
PdDestroyOffscreenLock(surface->hwdata->offscreenctx);
PhDCRelease(surface->hwdata->offscreenctx);
SDL_SetError
("ph_AllocHWSurface(): GetGraphicsHWCaps() function failed !\n");
return -1;
}
this->info.video_mem = hwcaps.currently_available_video_ram / 1024;
return 0;
}
void
ph_FreeHWSurface(_THIS, SDL_Surface * surface)
{
PgHWCaps_t hwcaps;
if (surface->hwdata == NULL) {
SDL_SetError("ph_FreeHWSurface(): no hwdata!\n");
return;
}
if (surface->hwdata->offscreenctx == NULL) {
SDL_SetError("ph_FreeHWSurface(): no offscreen context to delete!\n");
return;
}
#if 0 /* FIXME */
/* unlock the offscreen context if it has been locked before destroy it */
if (PdIsOffscreenLocked(surface->hwdata->offscreenctx) == Pg_OSC_LOCKED) {
PdUnlockOffscreen(surface->hwdata->offscreenctx);
}
PdDestroyOffscreenLock(surface->hwdata->offscreenctx);
#endif /* 0 */
PhDCRelease(surface->hwdata->offscreenctx);
SDL_free(surface->hwdata);
surface->hwdata = NULL;
/* Update video ram amount */
if (PgGetGraphicsHWCaps(&hwcaps) < 0) {
SDL_SetError
("ph_FreeHWSurface(): GetGraphicsHWCaps() function failed !\n");
return;
}
this->info.video_mem = hwcaps.currently_available_video_ram / 1024;
return;
}
int
ph_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst)
{
if ((src->hwdata == NULL) && (src != this->screen)) {
SDL_SetError
("ph_CheckHWBlit(): Source surface haven't hardware specific data.\n");
src->flags &= ~SDL_HWACCEL;
return -1;
}
if ((src->flags & SDL_HWSURFACE) != SDL_HWSURFACE) {
SDL_SetError
("ph_CheckHWBlit(): Source surface isn't a hardware surface.\n");
src->flags &= ~SDL_HWACCEL;
return -1;
}
if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
if (this->info.blit_hw_CC != 1) {
src->flags &= ~SDL_HWACCEL;
src->map->hw_blit = NULL;
return -1;
}
}
if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
if (this->info.blit_hw_A != 1) {
src->flags &= ~SDL_HWACCEL;
src->map->hw_blit = NULL;
return -1;
}
}
src->flags |= SDL_HWACCEL;
src->map->hw_blit = ph_HWAccelBlit;
return 1;
}
PgColor_t
ph_ExpandColor(_THIS, SDL_Surface * surface, Uint32 color)
{
Uint32 truecolor;
/* Photon API accepts true colors only during hw filling operations */
switch (surface->format->BitsPerPixel) {
case 8:
{
if ((surface->format->palette)
&& (color <= surface->format->palette->ncolors)) {
truecolor =
PgRGB(surface->format->palette->colors[color].r,
surface->format->palette->colors[color].g,
surface->format->palette->colors[color].b);
} else {
SDL_SetError
("ph_ExpandColor(): Color out of range for the 8bpp mode !\n");
return 0xFFFFFFFFUL;
}
}
break;
case 15:
{
truecolor = ((color & 0x00007C00UL) << 9) | /* R */
((color & 0x000003E0UL) << 6) | /* G */
((color & 0x0000001FUL) << 3) | /* B */
((color & 0x00007000UL) << 4) | /* R compensation */
((color & 0x00000380UL) << 1) | /* G compensation */
((color & 0x0000001CUL) >> 2); /* B compensation */
}
break;
case 16:
{
truecolor = ((color & 0x0000F800UL) << 8) | /* R */
((color & 0x000007E0UL) << 5) | /* G */
((color & 0x0000001FUL) << 3) | /* B */
((color & 0x0000E000UL) << 3) | /* R compensation */
((color & 0x00000600UL) >> 1) | /* G compensation */
((color & 0x0000001CUL) >> 2); /* B compensation */
}
break;
case 24:
{
truecolor = color & 0x00FFFFFFUL;
}
break;
case 32:
{
truecolor = color;
}
break;
default:
{
SDL_SetError
("ph_ExpandColor(): Unsupported depth for the hardware operations !\n");
return 0xFFFFFFFFUL;
}
}
return truecolor;
}
int
ph_FillHWRect(_THIS, SDL_Surface * surface, SDL_Rect * rect, Uint32 color)
{
PgColor_t oldcolor;
Uint32 truecolor;
int ydisp = 0;
if (this->info.blit_fill != 1) {
return -1;
}
truecolor = ph_ExpandColor(this, surface, color);
if (truecolor == 0xFFFFFFFFUL) {
return -1;
}
oldcolor = PgSetFillColor(truecolor);
/* 640x400 videomode emulation */
if (videomode_emulatemode == 1) {
ydisp += 40;
}
PgDrawIRect(rect->x, rect->y + ydisp, rect->w + rect->x - 1,
rect->h + rect->y + ydisp - 1, Pg_DRAW_FILL);
PgSetFillColor(oldcolor);
PgFlush();
PgWaitHWIdle();
return 0;
}
int
ph_FlipHWSurface(_THIS, SDL_Surface * screen)
{
PhArea_t farea;
if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) {
/* flush all drawing ops before blitting */
PgFlush();
PgWaitHWIdle();
farea.pos.x = 0;
farea.pos.y = 0;
farea.size.w = screen->w;
farea.size.h = screen->h;
/* emulate 640x400 videomode */
if (videomode_emulatemode == 1) {
farea.pos.y += 40;
}
PgContextBlitArea(OCImage.offscreen_context, &farea,
OCImage.offscreen_backcontext, &farea);
/* flush the blitting */
PgFlush();
PgWaitHWIdle();
}
return 0;
}
int
ph_LockHWSurface(_THIS, SDL_Surface * surface)
{
#if 0 /* FIXME */
int lockresult;
if (surface->hwdata == NULL) {
return;
}
surface->hwdata->lockparam.flags = 0;
surface->hwdata->lockparam.time_out = NULL;
lockresult =
PdLockOffscreen(surface->hwdata->offscreenctx,
&surface->hwdata->lockparam);
switch (lockresult) {
case EOK:
break;
case Pg_OSC_LOCK_DEADLOCK:
SDL_SetError("ph_LockHWSurface(): Deadlock detected !\n");
return -1;
case Pg_OSC_LOCK_INVALID:
SDL_SetError("ph_LockHWSurface(): Lock invalid !\n");
return -1;
default:
SDL_SetError("ph_LockHWSurface(): Can't lock the surface !\n");
return -1;
}
#endif /* 0 */
return 0;
}
void
ph_UnlockHWSurface(_THIS, SDL_Surface * surface)
{
#if 0 /* FIXME */
int unlockresult;
if ((surface == NULL) || (surface->hwdata == NULL)) {
return;
}
if (PdIsOffscreenLocked(surface->hwdata->offscreenctx) == Pg_OSC_LOCKED) {
unlockresult = PdUnlockOffscreen(surface->hwdata->offscreenctx);
}
#endif /* 0 */
return;
}
int
ph_HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst,
SDL_Rect * dstrect)
{
SDL_VideoDevice *this = current_video;
PhArea_t srcarea;
PhArea_t dstarea;
int ydisp = 0;
/* 640x400 videomode emulation */
if (videomode_emulatemode == 1) {
ydisp += 40;
}
srcarea.pos.x = srcrect->x;
srcarea.pos.y = srcrect->y;
srcarea.size.w = srcrect->w;
srcarea.size.h = srcrect->h;
dstarea.pos.x = dstrect->x;
dstarea.pos.y = dstrect->y;
dstarea.size.w = dstrect->w;
dstarea.size.h = dstrect->h;
if (((src == this->screen) || (src->hwdata != NULL))
&& ((dst == this->screen) || (dst->hwdata != NULL))) {
if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
ph_SetHWColorKey(this, src, src->format->colorkey);
PgChromaOn();
}
if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
ph_SetHWAlpha(this, src, src->format->alpha);
PgAlphaOn();
}
if (dst == this->screen) {
if (src == this->screen) {
/* blitting from main screen to main screen */
dstarea.pos.y += ydisp;
srcarea.pos.y += ydisp;
PgContextBlitArea(OCImage.offscreen_context, &srcarea,
OCImage.offscreen_context, &dstarea);
} else {
/* blitting from offscreen to main screen */
dstarea.pos.y += ydisp;
PgContextBlitArea(src->hwdata->offscreenctx, &srcarea,
OCImage.offscreen_context, &dstarea);
}
} else {
if (src == this->screen) {
/* blitting from main screen to offscreen */
srcarea.pos.y += ydisp;
PgContextBlitArea(OCImage.offscreen_context, &srcarea,
dst->hwdata->offscreenctx, &dstarea);
} else {
/* blitting offscreen to offscreen */
PgContextBlitArea(src->hwdata->offscreenctx, &srcarea,
dst->hwdata->offscreenctx, &dstarea);
}
}
if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
PgAlphaOff();
}
if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
PgChromaOff();
}
} else {
SDL_SetError
("ph_HWAccelBlit(): Source or target surface is not a hardware surface !\n");
return -1;
}
PgFlush();
PgWaitHWIdle();
return 0;
}
int
ph_SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key)
{
if (this->info.blit_hw_CC != 1) {
return -1;
}
if (surface->hwdata != NULL) {
surface->hwdata->colorkey = ph_ExpandColor(this, surface, key);
if (surface->hwdata->colorkey == 0xFFFFFFFFUL) {
return -1;
}
}
PgSetChroma(surface->hwdata->colorkey,
Pg_CHROMA_SRC_MATCH | Pg_CHROMA_NODRAW);
return 0;
}
int
ph_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha)
{
if (this->info.blit_hw_A != 1) {
return -1;
}
PgSetAlphaBlend(NULL, alpha);
return 0;
}
#if SDL_VIDEO_OPENGL
void
ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect * rects)
{
this->GL_SwapBuffers(this);
return;
}
#endif /* SDL_VIDEO_OPENGL */
void
ph_NormalUpdate(_THIS, int numrects, SDL_Rect * rects)
{
PhPoint_t ph_pos;
PhRect_t ph_rect;
int i;
for (i = 0; i < numrects; ++i) {
if (rects[i].w == 0) { /* Clipped? dunno why but this occurs sometime. */
continue;
}
if (rects[i].h == 0) { /* Clipped? dunno why but this occurs sometime. */
continue;
}
ph_pos.x = rects[i].x;
ph_pos.y = rects[i].y;
ph_rect.ul.x = rects[i].x;
ph_rect.ul.y = rects[i].y;
ph_rect.lr.x = rects[i].x + rects[i].w;
ph_rect.lr.y = rects[i].y + rects[i].h;
if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0) {
SDL_SetError("ph_NormalUpdate(): PgDrawPhImageRectmx failed!\n");
return;
}
}
if (PgFlush() < 0) {
SDL_SetError("ph_NormalUpdate(): PgFlush() function failed!\n");
}
}
void
ph_OCUpdate(_THIS, int numrects, SDL_Rect * rects)
{
int i;
PhPoint_t zero = { 0, 0 };
PhArea_t src_rect;
PhArea_t dest_rect;
PgSetTranslation(&zero, 0);
PgSetRegion(PtWidgetRid(window));
PgSetClipping(0, NULL);
PgFlush();
PgWaitHWIdle();
for (i = 0; i < numrects; ++i) {
if (rects[i].w == 0) { /* Clipped? */
continue;
}
if (rects[i].h == 0) { /* Clipped? */
continue;
}
src_rect.pos.x = rects[i].x;
src_rect.pos.y = rects[i].y;
dest_rect.pos.x = rects[i].x;
dest_rect.pos.y = rects[i].y;
src_rect.size.w = rects[i].w;
src_rect.size.h = rects[i].h;
dest_rect.size.w = rects[i].w;
dest_rect.size.h = rects[i].h;
PgContextBlitArea(OCImage.offscreen_context, &src_rect, NULL,
&dest_rect);
}
if (PgFlush() < 0) {
SDL_SetError("ph_OCUpdate(): PgFlush failed.\n");
}
}
void
ph_OCDCUpdate(_THIS, int numrects, SDL_Rect * rects)
{
PgWaitHWIdle();
if (PgFlush() < 0) {
SDL_SetError("ph_OCDCUpdate(): PgFlush failed.\n");
}
}
/* vi: set ts=4 sw=4 expandtab: */