Home | History | Annotate | Download | only in cybergfx
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2006 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 "SDL_endian.h"
     25 #include "SDL_cgximage_c.h"
     26 
     27 #ifdef HAVE_KSTAT
     28 #include <kstat.h>
     29 #endif
     30 
     31 #ifdef USE_CGX_WRITELUTPIXEL
     32 #if defined(__SASC) || defined(__PPC__)
     33 	#define WLUT WriteLUTPixelArray
     34 #else
     35 void WLUT(APTR a,UWORD b,UWORD c,UWORD d,struct RastPort *e,APTR f,UWORD g,UWORD h,UWORD i,UWORD l,UBYTE m)
     36 {	WriteLUTPixelArray(a,b,c,d,e,f,g,h,i,l,m); }
     37 #endif
     38 
     39 #endif
     40 
     41 /* Various screen update functions available */
     42 static void CGX_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
     43 static void CGX_FakeUpdate(_THIS, int numrects, SDL_Rect *rects);
     44 
     45 BOOL SafeDisp=TRUE,SafeChange=TRUE;
     46 struct MsgPort *safeport=NULL,*dispport=NULL;
     47 ULONG safe_sigbit,disp_sigbit;
     48 int use_picasso96=1;
     49 
     50 int CGX_SetupImage(_THIS, SDL_Surface *screen)
     51 {
     52 	SDL_Ximage=NULL;
     53 
     54 	if(screen->flags&SDL_HWSURFACE) {
     55 		ULONG pitch;
     56 
     57 		if(!screen->hwdata) {
     58 			if(!(screen->hwdata=SDL_malloc(sizeof(struct private_hwdata))))
     59 				return -1;
     60 
     61 			D(bug("Creating system accel struct\n"));
     62 		}
     63 		screen->hwdata->lock=NULL;
     64 		screen->hwdata->allocated=0;
     65 		screen->hwdata->mask=NULL;
     66 		screen->hwdata->bmap=SDL_RastPort->BitMap;
     67 		screen->hwdata->videodata=this;
     68 
     69 		if(!(screen->hwdata->lock=LockBitMapTags(screen->hwdata->bmap,
     70 				LBMI_BASEADDRESS,(ULONG)&screen->pixels,
     71 				LBMI_BYTESPERROW,(ULONG)&pitch,TAG_DONE))) {
     72 			SDL_free(screen->hwdata);
     73 			screen->hwdata=NULL;
     74 			return -1;
     75 		}
     76 		else {
     77 			UnLockBitMap(screen->hwdata->lock);
     78 			screen->hwdata->lock=NULL;
     79 		}
     80 
     81 		screen->pitch=pitch;
     82 
     83 		this->UpdateRects = CGX_FakeUpdate;
     84 
     85 		D(bug("Accel video image configured (%lx, pitch %ld).\n",screen->pixels,screen->pitch));
     86 		return 0;
     87 	}
     88 
     89 	screen->pixels = SDL_malloc(screen->h*screen->pitch);
     90 
     91 	if ( screen->pixels == NULL ) {
     92 		SDL_OutOfMemory();
     93 		return(-1);
     94 	}
     95 
     96 	SDL_Ximage=screen->pixels;
     97 
     98 	if ( SDL_Ximage == NULL ) {
     99 		SDL_SetError("Couldn't create XImage");
    100 		return(-1);
    101 	}
    102 
    103 	this->UpdateRects = CGX_NormalUpdate;
    104 
    105 	return(0);
    106 }
    107 
    108 void CGX_DestroyImage(_THIS, SDL_Surface *screen)
    109 {
    110 	if ( SDL_Ximage ) {
    111 		SDL_free(SDL_Ximage);
    112 		SDL_Ximage = NULL;
    113 	}
    114 	if ( screen ) {
    115 		screen->pixels = NULL;
    116 
    117 		if(screen->hwdata) {
    118 			SDL_free(screen->hwdata);
    119 			screen->hwdata=NULL;
    120 		}
    121 	}
    122 }
    123 
    124 /* This is a hack to see whether this system has more than 1 CPU */
    125 static int num_CPU(void)
    126 {
    127 	return 1;
    128 }
    129 
    130 int CGX_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags)
    131 {
    132 	int retval;
    133 
    134 	D(bug("Calling ResizeImage()\n"));
    135 
    136 	CGX_DestroyImage(this, screen);
    137 
    138 	if ( flags & SDL_OPENGL ) {  /* No image when using GL */
    139         	retval = 0;
    140 	} else {
    141 		retval = CGX_SetupImage(this, screen);
    142 		/* We support asynchronous blitting on the display */
    143 		if ( flags & SDL_ASYNCBLIT ) {
    144 			if ( num_CPU() > 1 ) {
    145 				screen->flags |= SDL_ASYNCBLIT;
    146 			}
    147 		}
    148 	}
    149 	return(retval);
    150 }
    151 
    152 int CGX_AllocHWSurface(_THIS, SDL_Surface *surface)
    153 {
    154 	D(bug("Alloc HW surface...%ld x %ld x %ld!\n",surface->w,surface->h,this->hidden->depth));
    155 
    156 	if(surface==SDL_VideoSurface)
    157 	{
    158 		D(bug("Allocation skipped, it's system one!\n"));
    159 		return 0;
    160 	}
    161 
    162 	if(!surface->hwdata)
    163 	{
    164 		if(!(surface->hwdata=SDL_malloc(sizeof(struct private_hwdata))))
    165 			return -1;
    166 	}
    167 
    168 	surface->hwdata->mask=NULL;
    169 	surface->hwdata->lock=NULL;
    170 	surface->hwdata->videodata=this;
    171 	surface->hwdata->allocated=0;
    172 
    173 	if(surface->hwdata->bmap=AllocBitMap(surface->w,surface->h,this->hidden->depth,BMF_MINPLANES,SDL_Display->RastPort.BitMap))
    174 	{
    175 		surface->hwdata->allocated=1;
    176 		surface->flags|=SDL_HWSURFACE;
    177 		D(bug("...OK\n"));
    178 		return 0;
    179 	}
    180 	else
    181 	{
    182 		SDL_free(surface->hwdata);
    183 		surface->hwdata=NULL;
    184 	}
    185 
    186 	return(-1);
    187 }
    188 void CGX_FreeHWSurface(_THIS, SDL_Surface *surface)
    189 {
    190 	if(surface && surface!=SDL_VideoSurface && surface->hwdata)
    191 	{
    192 		D(bug("Free hw surface.\n"));
    193 
    194 		if(surface->hwdata->mask)
    195 			SDL_free(surface->hwdata->mask);
    196 
    197 		if(surface->hwdata->bmap&&surface->hwdata->allocated)
    198 			FreeBitMap(surface->hwdata->bmap);
    199 
    200 		SDL_free(surface->hwdata);
    201 		surface->hwdata=NULL;
    202 		surface->pixels=NULL;
    203 		D(bug("end of free hw surface\n"));
    204 	}
    205 	return;
    206 }
    207 
    208 int CGX_LockHWSurface(_THIS, SDL_Surface *surface)
    209 {
    210 	if (surface->hwdata)
    211 	{
    212 //		D(bug("Locking a bitmap...\n"));
    213 		if(!surface->hwdata->lock)
    214 		{
    215 			Uint32 pitch;
    216 
    217 			if(!(surface->hwdata->lock=LockBitMapTags(surface->hwdata->bmap,
    218 					LBMI_BASEADDRESS,(ULONG)&surface->pixels,
    219 					LBMI_BYTESPERROW,(ULONG)&pitch,TAG_DONE)))
    220 				return -1;
    221 
    222 // surface->pitch e' a 16bit!
    223 
    224 			surface->pitch=pitch;
    225 
    226 			if(!currently_fullscreen&&surface==SDL_VideoSurface)
    227 				surface->pixels=((char *)surface->pixels)+(surface->pitch*(SDL_Window->BorderTop+SDL_Window->TopEdge)+
    228 					surface->format->BytesPerPixel*(SDL_Window->BorderLeft+SDL_Window->LeftEdge));
    229 		}
    230 		D(else bug("Already locked!!!\n"));
    231 	}
    232 	return(0);
    233 }
    234 
    235 void CGX_UnlockHWSurface(_THIS, SDL_Surface *surface)
    236 {
    237 	if(surface->hwdata && surface->hwdata->lock)
    238 	{
    239 		UnLockBitMap(surface->hwdata->lock);
    240 		surface->hwdata->lock=NULL;
    241 //		surface->pixels=NULL;
    242 	}
    243 }
    244 
    245 int CGX_FlipHWSurface(_THIS, SDL_Surface *surface)
    246 {
    247 	static int current=0;
    248 
    249 	if(this->hidden->dbuffer)
    250 	{
    251 		if(!SafeChange)
    252 		{
    253 			Wait(disp_sigbit);
    254 // Non faccio nulla, vuoto solo la porta
    255 			while(GetMsg(dispport)!=NULL)
    256 				;
    257 			SafeChange=TRUE;
    258 		}
    259 
    260 		if(ChangeScreenBuffer(SDL_Display,this->hidden->SB[current^1]))
    261 		{
    262 			surface->hwdata->bmap=SDL_RastPort->BitMap=this->hidden->SB[current]->sb_BitMap;
    263 			SafeChange=FALSE;
    264 			SafeDisp=FALSE;
    265 			current^=1;
    266 		}
    267 
    268 		if(!SafeDisp)
    269 		{
    270 			Wait(safe_sigbit);
    271 			while(GetMsg(safeport)!=NULL)
    272 				;
    273 			SafeDisp=TRUE;
    274 		}
    275 
    276 	}
    277 	return(0);
    278 }
    279 
    280 /* Byte-swap the pixels in the display image */
    281 static void CGX_SwapAllPixels(SDL_Surface *screen)
    282 {
    283 	int x, y;
    284 
    285 	switch (screen->format->BytesPerPixel) {
    286 	    case 2: {
    287 		Uint16 *spot;
    288 		for ( y=0; y<screen->h; ++y ) {
    289 			spot = (Uint16 *) ((Uint8 *)screen->pixels +
    290 						y * screen->pitch);
    291 			for ( x=0; x<screen->w; ++x, ++spot ) {
    292 				*spot = SDL_Swap16(*spot);
    293 			}
    294 		}
    295 	    }
    296 	    break;
    297 
    298 	    case 4: {
    299 		Uint32 *spot;
    300 		for ( y=0; y<screen->h; ++y ) {
    301 			spot = (Uint32 *) ((Uint8 *)screen->pixels +
    302 						y * screen->pitch);
    303 			for ( x=0; x<screen->w; ++x, ++spot ) {
    304 				*spot = SDL_Swap32(*spot);
    305 			}
    306 		}
    307 	    }
    308 	    break;
    309 
    310 	    default:
    311 		/* should never get here */
    312 		break;
    313 	}
    314 }
    315 static void CGX_SwapPixels(SDL_Surface *screen, int numrects, SDL_Rect *rects)
    316 {
    317 	int i;
    318 	int x, minx, maxx;
    319 	int y, miny, maxy;
    320 
    321 	switch (screen->format->BytesPerPixel) {
    322 	    case 2: {
    323 		Uint16 *spot;
    324 		for ( i=0; i<numrects; ++i ) {
    325 			minx = rects[i].x;
    326 			maxx = rects[i].x+rects[i].w;
    327 			miny = rects[i].y;
    328 			maxy = rects[i].y+rects[i].h;
    329 			for ( y=miny; y<maxy; ++y ) {
    330 				spot = (Uint16 *) ((Uint8 *)screen->pixels +
    331 						y * screen->pitch + minx * 2);
    332 				for ( x=minx; x<maxx; ++x, ++spot ) {
    333 					*spot = SDL_Swap16(*spot);
    334 				}
    335 			}
    336 		}
    337 	    }
    338 	    break;
    339 
    340 	    case 4: {
    341 		Uint32 *spot;
    342 		for ( i=0; i<numrects; ++i ) {
    343 			minx = rects[i].x;
    344 			maxx = rects[i].x+rects[i].w;
    345 			miny = rects[i].y;
    346 			maxy = rects[i].y+rects[i].h;
    347 			for ( y=miny; y<maxy; ++y ) {
    348 				spot = (Uint32 *) ((Uint8 *)screen->pixels +
    349 						y * screen->pitch + minx * 4);
    350 				for ( x=minx; x<maxx; ++x, ++spot ) {
    351 					*spot = SDL_Swap32(*spot);
    352 				}
    353 			}
    354 		}
    355 	    }
    356 	    break;
    357 
    358 	    default:
    359 		/* should never get here */
    360 		break;
    361 	}
    362 }
    363 
    364 #ifdef __SASC
    365 
    366 #define USE_WPA WritePixelArray
    367 #else
    368 
    369 void USE_WPA(char *a,int b,int c,int d, struct RastPort *e,int f,int g, int h, int i, Uint32 l)
    370 {
    371 		WritePixelArray(a,b,c,d,e,f,g,h,i,l);
    372 }
    373 
    374 #endif
    375 
    376 static void CGX_FakeUpdate(_THIS, int numrects, SDL_Rect *rects)
    377 {
    378 }
    379 
    380 static void CGX_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
    381 {
    382 	int i,format,customroutine=0;
    383 #ifndef USE_CGX_WRITELUTPIXEL
    384 	int bpp;
    385 #endif
    386 	if(this->hidden->same_format && !use_picasso96)
    387 	{
    388 		format=RECTFMT_RAW;
    389 	}
    390 	else switch(this->screen->format->BytesPerPixel)
    391 	{
    392 		case 4:
    393 			format=RECTFMT_RGBA;
    394 			break;
    395 		case 3:
    396 			format=RECTFMT_RGB;
    397 			break;
    398 		case 2:
    399 			customroutine=1;
    400 			break;
    401 		case 1:
    402 //			D(bug("soft depth: 8 hardbpp: %ld\n",this->hidden->depth));
    403 			if(this->hidden->depth>8)
    404 			{
    405 #ifndef USE_CGX_WRITELUTPIXEL
    406 				if(this->hidden->depth>32)
    407 					customroutine=4;
    408 				else if(this->hidden->depth>16)
    409 				{
    410 					bpp=this->hidden->BytesPerPixel; // That one is the only one that needs bpp
    411 					customroutine=2; // The slow one!
    412 				}
    413 				else
    414 					customroutine=3;
    415 #else
    416 
    417 				customroutine=2;
    418 #endif
    419 
    420 //				format=RECTFMT_LUT8;   Vecchia funzione x usare la WritePixelArray.
    421 			}
    422 			else
    423 				customroutine=1;
    424 			break;
    425 		default:
    426 			D(bug("Unable to blit this surface!\n"));
    427 			return;
    428 	}
    429 
    430 	/* Check for endian-swapped X server, swap if necessary (VERY slow!) */
    431 	if ( swap_pixels &&
    432 	     ((this->screen->format->BytesPerPixel%2) == 0) ) {
    433 		D(bug("Software Swapping! SLOOOW!\n"));
    434 		CGX_SwapPixels(this->screen, numrects, rects);
    435 		for ( i=0; i<numrects; ++i ) {
    436 			if ( ! rects[i].w ) { /* Clipped? */
    437 				continue;
    438 			}
    439 			USE_WPA(this->screen->pixels,rects[i].x, rects[i].y,this->screen->pitch,
    440 					SDL_RastPort,SDL_Window->BorderLeft+rects[i].x,SDL_Window->BorderTop+rects[i].y,
    441 					rects[i].w,rects[i].h,format);
    442 		}
    443 		CGX_SwapPixels(this->screen, numrects, rects);
    444 	}
    445 	else if (customroutine==2)
    446 	{
    447 #ifdef USE_CGX_WRITELUTPIXEL
    448 		for ( i=0; i<numrects; ++i ) {
    449 			if ( ! rects[i].w ) { /* Clipped? */
    450 				continue;
    451 			}
    452 
    453 			WLUT(this->screen->pixels,rects[i].x, rects[i].y,this->screen->pitch,
    454 					SDL_RastPort,SDL_XPixels,SDL_Window->BorderLeft+rects[i].x,SDL_Window->BorderTop+rects[i].y,
    455 					rects[i].w,rects[i].h,CTABFMT_XRGB8);
    456 		}
    457 #else
    458 		unsigned char *bm_address;
    459 		Uint32	destpitch;
    460 		APTR handle;
    461 
    462 		if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,&bm_address,
    463 								LBMI_BYTESPERROW,&destpitch,TAG_DONE))
    464 		{
    465 			int srcwidth;
    466 			unsigned char *destbase;
    467 			register int j,k,t;
    468 			register unsigned char *mask,*dst;
    469 			register unsigned char *src,*dest;
    470 
    471 // Aggiungo il bordo della finestra se sono fullscreen.
    472 			if(currently_fullscreen)
    473 				destbase=bm_address;
    474 			else
    475 				destbase=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel;
    476 
    477 			for ( i=0; i<numrects; ++i )
    478 			{
    479 				srcwidth=rects[i].w;
    480 
    481 				if ( !srcwidth ) { /* Clipped? */
    482 					continue;
    483 				}
    484 
    485 				dest=destbase+rects[i].x*this->hidden->BytesPerPixel;
    486 				dest+=(rects[i].y*destpitch);
    487 				src=((char *)(this->screen->pixels))+rects[i].x;
    488 				src+=(rects[i].y*this->screen->pitch);
    489 
    490 				for(j=rects[i].h;j;--j)
    491 				{
    492 					dst=dest;
    493 // SLOW routine, used for 8->24 bit mapping
    494 					for(k=0;k<srcwidth;k++)
    495 					{
    496 						mask=(unsigned char *)(&SDL_XPixels[src[k]]);
    497 						for(t=0;t<bpp;t++)
    498 						{
    499 							dst[t]=mask[t];
    500 						}
    501 						dst+=bpp;
    502 					}
    503 					src+=this->screen->pitch;
    504 					dest+=destpitch;
    505 				}
    506 			}
    507 			UnLockBitMap(handle);
    508 		}
    509 	}
    510 	else if (customroutine==3)
    511 	{
    512 		unsigned char *bm_address;
    513 		Uint32	destpitch;
    514 		APTR handle;
    515 
    516 		if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,&bm_address,
    517 								LBMI_BYTESPERROW,&destpitch,TAG_DONE))
    518 		{
    519 			int srcwidth;
    520 			unsigned char *destbase;
    521 			register int j,k;
    522 			register unsigned char *src,*dest;
    523 			register Uint16 *destl,*srcl;
    524 
    525 			if(currently_fullscreen)
    526 				destbase=bm_address;
    527 			else
    528 				destbase=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel;
    529 
    530 			for ( i=0; i<numrects; ++i )
    531 			{
    532 				srcwidth=rects[i].w;
    533 
    534 				if ( !srcwidth ) { /* Clipped? */
    535 					continue;
    536 				}
    537 
    538 				dest=destbase+rects[i].x*this->hidden->BytesPerPixel;
    539 				dest+=(rects[i].y*destpitch);
    540 				src=((char *)(this->screen->pixels))+rects[i].x;
    541 				src+=(rects[i].y*this->screen->pitch);
    542 
    543 // This is the fast, well not too slow, remapping code for 16bit displays
    544 
    545 				for(j=rects[i].h;j;--j)
    546 				{
    547 					destl=(Uint16 *)dest;
    548 
    549 					for(k=0;k<srcwidth;k++)
    550 					{
    551 						srcl=(Uint16 *)&SDL_XPixels[src[k]];
    552 						*destl=*srcl;
    553 						destl++;
    554 					}
    555 					src+=this->screen->pitch;
    556 					dest+=destpitch;
    557 				}
    558 			}
    559 			UnLockBitMap(handle);
    560 		}
    561 	}
    562 	else if (customroutine==4)
    563 	{
    564 		unsigned char *bm_address;
    565 		Uint32	destpitch;
    566 		APTR handle;
    567 
    568 		if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,&bm_address,
    569 								LBMI_BYTESPERROW,&destpitch,TAG_DONE))
    570 		{
    571 			int srcwidth;
    572 			unsigned char *destbase;
    573 			register int j,k;
    574 			register unsigned char *src,*dest;
    575 			register Uint32 *destl,*srcl;
    576 
    577 			if(currently_fullscreen)
    578 				destbase=bm_address;
    579 			else
    580 				destbase=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel;
    581 
    582 			for ( i=0; i<numrects; ++i )
    583 			{
    584 				srcwidth=rects[i].w;
    585 
    586 				if ( !srcwidth ) { /* Clipped? */
    587 					continue;
    588 				}
    589 
    590 				dest=destbase+rects[i].x*this->hidden->BytesPerPixel;
    591 				dest+=(rects[i].y*destpitch);
    592 				src=((char *)(this->screen->pixels))+rects[i].x;
    593 				src+=(rects[i].y*this->screen->pitch);
    594 
    595 // This is the fast, well not too slow, remapping code for 32bit displays
    596 
    597 				for(j=rects[i].h;j;--j)
    598 				{
    599 					destl=(Uint32 *)dest;
    600 
    601 					for(k=0;k<srcwidth;k++)
    602 					{
    603 						srcl=(Uint32 *)&SDL_XPixels[src[k]];
    604 						*destl=*srcl;
    605 						destl++;
    606 					}
    607 					src+=this->screen->pitch;
    608 					dest+=destpitch;
    609 				}
    610 			}
    611 			UnLockBitMap(handle);
    612 		}
    613 #endif
    614 	}
    615 	else if(customroutine)
    616 	{
    617 		unsigned char *bm_address;
    618 		Uint32	destpitch;
    619 		APTR handle;
    620 
    621 //		D(bug("Using customroutine!\n"));
    622 
    623 		if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,(ULONG)&bm_address,
    624 								LBMI_BYTESPERROW,(ULONG)&destpitch,TAG_DONE))
    625 		{
    626 			unsigned char *destbase;
    627 			register int j,srcwidth;
    628 			register unsigned char *src,*dest;
    629 
    630 // Aggiungo il bordo della finestra se sono fullscreen.
    631 			if(currently_fullscreen)
    632 				destbase=bm_address;
    633 			else
    634 				destbase=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->screen->format->BytesPerPixel;
    635 
    636 			for ( i=0; i<numrects; ++i )
    637 			{
    638 				srcwidth=rects[i].w;
    639 
    640 				if ( !srcwidth ) { /* Clipped? */
    641 					continue;
    642 				}
    643 
    644 				dest=destbase+rects[i].x*this->screen->format->BytesPerPixel;
    645 				dest+=(rects[i].y*destpitch);
    646 				src=((char *)(this->screen->pixels))+rects[i].x*this->screen->format->BytesPerPixel;
    647 				src+=(rects[i].y*this->screen->pitch);
    648 
    649 				srcwidth*=this->screen->format->BytesPerPixel;
    650 
    651 //				D(bug("Rects: %ld,%ld %ld,%ld Src:%lx Dest:%lx\n",rects[i].x,rects[i].y,rects[i].w,rects[i].h,src,dest));
    652 
    653 				for(j=rects[i].h;j;--j)
    654 				{
    655 					SDL_memcpy(dest,src,srcwidth);
    656 					src+=this->screen->pitch;
    657 					dest+=destpitch;
    658 				}
    659 			}
    660 			UnLockBitMap(handle);
    661 //			D(bug("Rectblit addr: %lx pitch: %ld rects:%ld srcptr: %lx srcpitch: %ld\n",bm_address,destpitch,numrects,this->screen->pixels,this->screen->pitch));
    662 		}
    663 	}
    664 	else
    665 	{
    666 		for ( i=0; i<numrects; ++i ) {
    667 			if ( ! rects[i].w ) { /* Clipped? */
    668 				continue;
    669 			}
    670 			USE_WPA(this->screen->pixels,rects[i].x, rects[i].y,this->screen->pitch,
    671 					SDL_RastPort,SDL_Window->BorderLeft+rects[i].x,SDL_Window->BorderTop+rects[i].y,
    672 					rects[i].w,rects[i].h,format);
    673 		}
    674 	}
    675 }
    676 
    677 void CGX_RefreshDisplay(_THIS)
    678 {
    679 	int format,customroutine=0;
    680 #ifndef USE_CGX_WRITELUTPIXEL
    681 	int bpp;
    682 #endif
    683 	/* Don't refresh a display that doesn't have an image (like GL) */
    684 	if ( ! SDL_Ximage ) {
    685 		return;
    686 	}
    687 
    688 	if(this->hidden->same_format && !use_picasso96)
    689 	{
    690 		format=RECTFMT_RAW;
    691 	}
    692 	else switch(this->screen->format->BytesPerPixel)
    693 	{
    694 		case 4:
    695 			format=RECTFMT_RGBA;
    696 			break;
    697 		case 3:
    698 			format=RECTFMT_RGB;
    699 			break;
    700 		case 2:
    701 			customroutine=1;
    702 			break;
    703 		case 1:
    704 //			D(bug("soft depth: 8 hardbpp: %ld\n",this->hidden->depth));
    705 			if(this->hidden->depth>8)
    706 			{
    707 #ifndef USE_CGX_WRITELUTPIXEL
    708 				if(this->hidden->depth>32)
    709 					customroutine=4;
    710 				else if(this->hidden->depth>16)
    711 				{
    712 					bpp=this->hidden->BytesPerPixel; // That one is the only one that needs bpp
    713 					customroutine=2; // The slow one!
    714 				}
    715 				else
    716 					customroutine=3;
    717 #else
    718 
    719 				customroutine=2;
    720 #endif
    721 //				format=RECTFMT_LUT8;
    722 			}
    723 			else
    724 				customroutine=1;
    725 			break;
    726 
    727 	}
    728 
    729 		/* Check for endian-swapped X server, swap if necessary */
    730 	if ( swap_pixels &&
    731 	     ((this->screen->format->BytesPerPixel%2) == 0) ) {
    732 		CGX_SwapAllPixels(this->screen);
    733 		USE_WPA(this->screen->pixels,0,0,this->screen->pitch,
    734 				SDL_RastPort,SDL_Window->BorderLeft,SDL_Window->BorderTop,
    735 				this->screen->w,this->screen->h,format);
    736 		CGX_SwapAllPixels(this->screen);
    737 	}
    738 	else if (customroutine==2)
    739 	{
    740 #ifdef USE_CGX_WRITELUTPIXEL
    741 		WLUT(this->screen->pixels,0,0,this->screen->pitch,
    742 					SDL_RastPort,SDL_XPixels,SDL_Window->BorderLeft,SDL_Window->BorderTop,
    743 					this->screen->w,this->screen->h,CTABFMT_XRGB8);
    744 #else
    745 		unsigned char *bm_address;
    746 		Uint32	destpitch;
    747 		APTR handle;
    748 
    749 		if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,(ULONG)&bm_address,
    750 								LBMI_BYTESPERROW,(ULONG)&destpitch,TAG_DONE))
    751 		{
    752 			register int j,k,t;
    753 			register unsigned char *mask,*dst;
    754 			register unsigned char *src,*dest;
    755 
    756 // Aggiungo il bordo della finestra se sono fullscreen.
    757 			if(!currently_fullscreen)
    758 				dest=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel;
    759 			else
    760 				dest=bm_address;
    761 
    762 			src=this->screen->pixels;
    763 
    764 			for(j=this->screen->h;j;--j)
    765 			{
    766 				dst=dest;
    767 // SLOW routine, used for 8->24 bit mapping
    768 				for(k=0;k<this->screen->w;k++)
    769 				{
    770 					mask=(unsigned char *)(&SDL_XPixels[src[k]]);
    771 					for(t=0;t<bpp;t++)
    772 					{
    773 						dst[t]=mask[t];
    774 					}
    775 					dst+=bpp;
    776 				}
    777 				src+=this->screen->pitch;
    778 				dest+=destpitch;
    779 			}
    780 			UnLockBitMap(handle);
    781 		}
    782 	}
    783 	else if (customroutine==3)
    784 	{
    785 		unsigned char *bm_address;
    786 		Uint32	destpitch;
    787 		APTR handle;
    788 
    789 		if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,(ULONG)&bm_address,
    790 								LBMI_BYTESPERROW,(ULONG)&destpitch,TAG_DONE))
    791 		{
    792 			register int j,k;
    793 			register unsigned char *src,*dest;
    794 			register Uint16 *destl,*srcl;
    795 
    796 			if(!currently_fullscreen)
    797 				dest=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel;
    798 			else
    799 				dest=bm_address;
    800 
    801 			src=this->screen->pixels;
    802 
    803 // This is the fast, well not too slow, remapping code for 16bit displays
    804 
    805 			for(j=this->screen->h;j;--j)
    806 			{
    807 				destl=(Uint16 *)dest;
    808 
    809 				for(k=0;k<this->screen->w;k++)
    810 				{
    811 					srcl=(Uint16 *)&SDL_XPixels[src[k]];
    812 					*destl=*srcl;
    813 					destl++;
    814 				}
    815 				src+=this->screen->pitch;
    816 				dest+=destpitch;
    817 			}
    818 			UnLockBitMap(handle);
    819 		}
    820 	}
    821 	else if (customroutine==4)
    822 	{
    823 		unsigned char *bm_address;
    824 		Uint32	destpitch;
    825 		APTR handle;
    826 
    827 		if(handle=LockBitMapTags(SDL_RastPort->BitMap,LBMI_BASEADDRESS,(ULONG)&bm_address,
    828 								LBMI_BYTESPERROW,(ULONG)&destpitch,TAG_DONE))
    829 		{
    830 			register int j,k;
    831 			register unsigned char *src,*dest;
    832 			register Uint32 *destl,*srcl;
    833 
    834 			if(!currently_fullscreen)
    835 				dest=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->hidden->BytesPerPixel;
    836 			else
    837 				dest=bm_address;
    838 
    839 			src=this->screen->pixels;
    840 
    841 // This is the fast, well not too slow, remapping code for 32bit displays
    842 
    843 			for(j=this->screen->h;j;--j)
    844 			{
    845 				destl=(Uint32 *)dest;
    846 
    847 				for(k=0;k<this->screen->w;k++)
    848 				{
    849 					srcl=(Uint32 *)&SDL_XPixels[src[k]];
    850 					*destl=*srcl;
    851 					destl++;
    852 				}
    853 				src+=this->screen->pitch;
    854 				dest+=destpitch;
    855 			}
    856 			UnLockBitMap(handle);
    857 		}
    858 #endif
    859 	}
    860 	else if(customroutine)
    861 	{
    862 		unsigned char *bm_address;
    863 		Uint32	destpitch;
    864 		APTR handle;
    865 
    866 		if(handle=LockBitMapTags(SDL_RastPort->BitMap,
    867 					LBMI_BASEADDRESS,(ULONG)&bm_address,
    868 					LBMI_BYTESPERROW,(ULONG)&destpitch,TAG_DONE))
    869 		{
    870 			register int j;
    871 			register unsigned char *src,*dest;
    872 
    873 			if(!currently_fullscreen)
    874 				dest=bm_address+(SDL_Window->TopEdge+SDL_Window->BorderTop)*destpitch+(SDL_Window->BorderLeft+SDL_Window->LeftEdge)*this->screen->format->BytesPerPixel;
    875 			else
    876 				dest=bm_address;
    877 
    878 			src=this->screen->pixels;
    879 
    880 //			D(bug("addr: %lx pitch: %ld src:%lx srcpitch: %ld\n",dest,destpitch,this->screen->pixels,this->screen->pitch));
    881 
    882 			if(this->screen->pitch==destpitch)
    883 			{
    884 				SDL_memcpy(dest,src,this->screen->pitch*this->screen->h);
    885 			}
    886 			else
    887 			{
    888 				for(j=this->screen->h;j;--j)
    889 				{
    890 					SDL_memcpy(dest,src,this->screen->pitch);
    891 					src+=this->screen->pitch;
    892 					dest+=destpitch;
    893 				}
    894 			}
    895 
    896 			UnLockBitMap(handle);
    897 		}
    898 	}
    899 	else
    900 	{
    901 		USE_WPA(this->screen->pixels,0,0,this->screen->pitch,
    902 				SDL_RastPort,SDL_Window->BorderLeft,SDL_Window->BorderTop,
    903 				this->screen->w,this->screen->h,format);
    904 	}
    905 
    906 }
    907