Mercurial > sdl-ios-xcode
diff src/video/photon/SDL_ph_image.c @ 0:74212992fb08
Initial revision
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Thu, 26 Apr 2001 16:45:43 +0000 |
parents | |
children | 8cc4dbfab9ab |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/photon/SDL_ph_image.c Thu Apr 26 16:45:43 2001 +0000 @@ -0,0 +1,348 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include <stdlib.h> +#include <Ph.h> +#include <photon/Pg.h> + +#include "SDL_error.h" +#include "SDL_endian.h" +#include "SDL_ph_image_c.h" + +//printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__ ); + +/* Various screen update functions available */ +//static void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); +//static void ph_DummyUpdate(_THIS, int numrects, SDL_Rect *rects); + +int ph_SetupImage(_THIS, SDL_Surface *screen) +{ + int type = 0; + + /* Determine image type */ + switch(screen->format->BitsPerPixel) + { + 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:{ + /* should never get here */ + fprintf(stderr,"error: unsupported bbp = %d\n", + screen->format->BitsPerPixel); + return -1; + } + break; + } + + //using shared memory for speed (set last param to 1) + if ((SDL_Image = PhCreateImage( NULL, screen->w, screen->h, type, NULL, 0, 1 )) + == NULL) + { + fprintf(stderr,"error: PhCreateImage failed.\n"); + return -1; + } + + screen->pixels = SDL_Image->image; + + this->UpdateRects = ph_NormalUpdate; + + return 0; +} + +int ph_SetupOCImage(_THIS, SDL_Surface *screen) //Offscreen context +{ + int type = 0; + + /* Determine image type */ + switch(screen->format->BitsPerPixel) + { + 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:{ + /* should never get here */ + fprintf(stderr,"error: unsupported bbp = %d\n", + screen->format->BitsPerPixel); + return -1; + } + break; + } + + OCImage.FrameData0 = (FRAMEDATA *) malloc((size_t)(sizeof( FRAMEDATA))); + OCImage.FrameData1 = (FRAMEDATA *) malloc((size_t)(sizeof( FRAMEDATA))); + + if(OCImage.direct_context == NULL) + OCImage.direct_context = PdCreateDirectContext(); + + OCImage.offscreen_context = PdCreateOffscreenContext(0,screen->w,screen->h, Pg_OSC_MEM_PAGE_ALIGN); + + if (OCImage.offscreen_context == NULL) + { + printf("PdCreateOffscreenContext failed\n"); + return -1; + } + + OCImage.Stride = OCImage.offscreen_context->pitch; + + if (OCImage.flags & SDL_DOUBLEBUF) + printf("hardware flag for doublebuf offscreen context\n"); + + + OCImage.dc_ptr.ptr8 = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context); + + OCImage.CurrentFrameData = OCImage.FrameData0; + OCImage.CurrentFrameData->Y = OCImage.dc_ptr.ptr8; + OCImage.CurrentFrameData->U = NULL; + OCImage.CurrentFrameData->V = NULL; + OCImage.current = 0; + + if(OCImage.dc_ptr.ptr8 == NULL) + { + printf("PdGetOffscreenContextPtr failed\n"); + return -1; + } + + PhDCSetCurrent(OCImage.offscreen_context); + + screen->pixels = OCImage.CurrentFrameData->Y; + + this->UpdateRects = ph_OCUpdate; + + return 0; +} + + +void ph_DestroyImage(_THIS, SDL_Surface *screen) +{ + + + if(SDL_Image == NULL) + return; + + if (OCImage.offscreen_context != NULL) + { + + PhDCRelease(OCImage.offscreen_context); + OCImage.offscreen_context = NULL; + free(OCImage.FrameData0); + OCImage.FrameData0 = NULL; + free(OCImage.FrameData1); + OCImage.FrameData1 = NULL; + } + + if (SDL_Image->image) + { + //free(SDL_Image->image); + //SDL_Image->image = NULL; + PhReleaseImage(SDL_Image); + SDL_Image = NULL; + } + + if ( screen ) { + screen->pixels = NULL; + } + + SDL_Image = NULL; +} + +int ph_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags) +{ + + ph_DestroyImage(this, screen); + + if( flags & SDL_HWSURFACE) + { + OCImage.flags = flags; //needed for SDL_DOUBLEBUF check + return ph_SetupOCImage(this,screen); + } + else if(flags & SDL_OPENGL) /* No image when using GL */ + { + return 0; + } + else + { + return ph_SetupImage(this, screen); + } + +} + +int ph_AllocHWSurface(_THIS, SDL_Surface *surface) +{ + + return(-1); +} + +void ph_FreeHWSurface(_THIS, SDL_Surface *surface) +{ + + return; +} + +int ph_FlipHWSurface(_THIS, SDL_Surface *surface) +{ + + return(0); +} + +int ph_LockHWSurface(_THIS, SDL_Surface *surface) +{ + + if ( (surface == SDL_VideoSurface) && blit_queued ) { +// XSync(GFX_Display, False); + PgFlush(); + blit_queued = 0; + } + return(0); +} + +void ph_UnlockHWSurface(_THIS, SDL_Surface *surface) +{ + + return; +} + +static PhPoint_t ph_pos; +static PhRect_t ph_rect; +static int i; + +void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) +{ + + for ( i=0; i<numrects; ++i ) + { + if ( rects[i].w == 0 ) { /* Clipped? */ + 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) + { + fprintf(stderr,"error: PgDrawPhImageRectmx failed.\n"); + } + } + if (PgFlush() < 0) + { + fprintf(stderr,"error: PgFlush failed.\n"); + } +} +void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects) +{ + PhPoint_t zero = {0}; + PhRect_t src_rect; + PhRect_t dest_rect; + + if(OCImage.direct_context == NULL) + { + return; + } + + PgSetRegion(PtWidgetRid(window)); + PgSetClipping(0,NULL); + PgWaitHWIdle(); + + + for ( i=0; i<numrects; ++i ) + { + if ( rects[i].w == 0 ) { /* Clipped? */ + continue; + } + + src_rect.ul.x=rects[i].x; + src_rect.ul.y=rects[i].y; + dest_rect.ul.x=rects[i].x; + dest_rect.ul.y=rects[i].y; + + dest_rect.lr.x=src_rect.lr.x= rects[i].x +rects[i].w; + dest_rect.lr.y=src_rect.lr.y= rects[i].y +rects[i].h; + + zero.x = zero.y = 0; + PgSetTranslation (&zero, 0); + PgSetRegion(PtWidgetRid(window)); + PgSetClipping(0,NULL); + PgContextBlitArea(OCImage.offscreen_context, (PhArea_t *)(&src_rect), NULL, (PhArea_t *)(&dest_rect)); + + } + if (PgFlush() < 0) + { + fprintf(stderr,"error: PgFlush failed.\n"); + } + + //later used to toggling double buffer + if(OCImage.current == 0) + { + OCImage.CurrentFrameData = OCImage.FrameData0; + } + else + { + OCImage.CurrentFrameData = OCImage.FrameData1; + } +} +