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;
+	}
+}
+