88
87
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
89
bool FrameBufferSoft::setVidMode(VideoMode mode)
88
bool FrameBufferSoft::setVidMode(VideoMode& mode)
91
myScreenDim.x = myScreenDim.y = 0;
92
myScreenDim.w = mode.screen_w;
93
myScreenDim.h = mode.screen_h;
95
myImageDim.x = mode.image_x;
96
myImageDim.y = mode.image_y;
97
myImageDim.w = mode.image_w;
98
myImageDim.h = mode.image_h;
100
myZoomLevel = mode.zoom;
102
90
// Make sure to clear the screen
105
93
SDL_FillRect(myScreen, NULL, 0);
106
94
SDL_UpdateRect(myScreen, 0, 0, 0, 0);
108
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags);
96
myScreen = SDL_SetVideoMode(mode.screen_w, mode.screen_h, 0, mySDLFlags);
109
97
if(myScreen == NULL)
111
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
100
buf << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
101
myOSystem->logMessage(buf.str(), 0);
114
104
myFormat = myScreen->format;
115
105
myBytesPerPixel = myFormat->BytesPerPixel;
117
// Make sure drawMediaSource() knows which renderer to use
118
stateChanged(myOSystem->eventHandler().state());
119
myBaseOffset = myImageDim.y * myPitch + myImageDim.x;
107
// Make sure the flags represent the current screen state
108
mySDLFlags = myScreen->flags;
110
// Make sure drawTIA() knows which renderer to use
111
switch(myBytesPerPixel)
114
myPitch = myScreen->pitch >> 1;
115
myRenderType = myUsePhosphor ? kPhosphor_16 : kSoftZoom_16;
118
myPitch = myScreen->pitch;
119
myRenderType = myUsePhosphor ? kPhosphor_24 : kSoftZoom_24;
122
myPitch = myScreen->pitch >> 2;
123
myRenderType = myUsePhosphor ? kPhosphor_32 : kSoftZoom_32;
126
myBaseOffset = mode.image_y * myPitch + mode.image_x;
128
// If software mode can open the given screen, it will always be in the
129
// requested format, or not at all; we only update mode when the screen
130
// is successfully created
131
mode.screen_w = myScreen->w;
132
mode.screen_h = myScreen->h;
133
myZoomLevel = mode.gfxmode.zoom;
134
// FIXME - look at gfxmode directly
121
136
// Erase old rects, since they've probably been scaled for
122
137
// a different sized screen
123
138
myRectList->start();
140
// Any previously allocated surfaces have probably changed as well,
141
// so we should refresh them
128
147
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
129
void FrameBufferSoft::drawMediaSource()
131
MediaSource& mediasrc = myOSystem->console().mediaSource();
133
uInt8* currentFrame = mediasrc.currentFrameBuffer();
134
uInt8* previousFrame = mediasrc.previousFrameBuffer();
136
uInt32 width = mediasrc.width();
137
uInt32 height = mediasrc.height();
148
void FrameBufferSoft::invalidate()
151
SDL_FillRect(myScreen, NULL, 0);
154
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
155
void FrameBufferSoft::drawTIA(bool fullRedraw)
157
const TIA& tia = myOSystem->console().tia();
159
uInt8* currentFrame = tia.currentFrameBuffer();
160
uInt8* previousFrame = tia.previousFrameBuffer();
162
uInt32 width = tia.width();
163
uInt32 height = tia.height();
139
165
switch(myRenderType)
368
403
bufofsY += width;
370
405
SDL_UnlockSurface(myScreen);
372
407
break; // kPhosphor_32
377
412
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
378
void FrameBufferSoft::preFrameUpdate()
382
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
383
413
void FrameBufferSoft::postFrameUpdate()
386
cerr << "FrameBufferSoft::postFrameUpdate()" << endl
387
<< " myInUIMode: " << myInUIMode << endl
388
<< " myRectList->numRects(): " << myRectList->numRects() << endl
389
<< " myDirtyFlag: " << myDirtyFlag << endl
392
if(myInUIMode && myRectList->numRects() > 0)
415
if(myTiaDirty && !myInUIMode)
417
SDL_UpdateRect(myScreen, 0, 0, 0, 0);
420
else if(myRectList->numRects() > 0)
422
//myRectList->print(myScreen->w, myScreen->h);
394
423
SDL_UpdateRects(myScreen, myRectList->numRects(), myRectList->rects());
396
else if(myDirtyFlag || myRectList->numRects() > 0)
428
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
429
void FrameBufferSoft::enablePhosphor(bool enable, int blend)
431
myUsePhosphor = enable;
432
myPhosphorBlend = blend;
434
// Make sure drawMediaSource() knows which renderer to use
435
switch(myBytesPerPixel)
438
myRenderType = myUsePhosphor ? kPhosphor_16 : kSoftZoom_16;
441
myRenderType = myUsePhosphor ? kPhosphor_24 : kSoftZoom_24;
444
myRenderType = myUsePhosphor ? kPhosphor_32 : kSoftZoom_32;
447
myRedrawEntireFrame = true;
450
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
451
FBSurface* FrameBufferSoft::createSurface(int w, int h, bool isBase) const
453
// For some unknown reason, OSX in software fullscreen mode doesn't like
454
// to use the underlying surface directly
455
// I suspect it's an SDL compatibility thing, since I get errors
456
// referencing Quartz vs. QuickDraw, and then a program crash
457
// For now, we'll just always use entire surfaces for OSX
458
// I don't think this will have much effect, since OpenGL mode is the
459
// preferred method in OSX (basically, all OSX installations have OpenGL
465
SDL_Surface* surface = isBase ? myScreen :
466
SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, myFormat->BitsPerPixel,
467
myFormat->Rmask, myFormat->Gmask, myFormat->Bmask,
470
return new FBSurfaceSoft(*this, surface, w, h, isBase);
404
473
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
450
520
SDL_UnlockSurface(myScreen);
453
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
454
void FrameBufferSoft::toggleFilter()
456
// No filter added yet ...
459
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
460
void FrameBufferSoft::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
524
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
525
// FBSurfaceSoft implementation follows ...
526
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
528
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
529
FBSurfaceSoft::FBSurfaceSoft(const FrameBufferSoft& buffer, SDL_Surface* surface,
530
uInt32 w, uInt32 h, bool isBase)
535
myIsBaseSurface(isBase),
536
mySurfaceIsDirty(false),
546
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
547
FBSurfaceSoft::~FBSurfaceSoft()
550
SDL_FreeSurface(mySurface);
553
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
554
void FBSurfaceSoft::hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color)
464
556
// Horizontal line
465
tmp.x = myImageDim.x + x * myZoomLevel;
466
tmp.y = myImageDim.y + y * myZoomLevel;
467
tmp.w = (x2 - x + 1) * myZoomLevel;
469
SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
558
tmp.x = x + myXOffset;
559
tmp.y = y + myYOffset;
562
SDL_FillRect(mySurface, &tmp, myFB.myDefPalette[color]);
472
565
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
473
void FrameBufferSoft::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
566
void FBSurfaceSoft::vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color)
478
tmp.x = myImageDim.x + x * myZoomLevel;
479
tmp.y = myImageDim.y + y * myZoomLevel;
481
tmp.h = (y2 - y + 1) * myZoomLevel;
482
SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
570
tmp.x = x + myXOffset;
571
tmp.y = y + myYOffset;
574
SDL_FillRect(mySurface, &tmp, myFB.myDefPalette[color]);
485
577
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
486
void FrameBufferSoft::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, int color)
578
void FBSurfaceSoft::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color)
490
580
// Fill the rectangle
491
tmp.x = myImageDim.x + x * myZoomLevel;
492
tmp.y = myImageDim.y + y * myZoomLevel;
493
tmp.w = w * myZoomLevel;
494
tmp.h = h * myZoomLevel;
495
SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
582
tmp.x = x + myXOffset;
583
tmp.y = y + myYOffset;
586
SDL_FillRect(mySurface, &tmp, myFB.myDefPalette[color]);
498
589
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
499
void FrameBufferSoft::drawChar(const GUI::Font* font, uInt8 chr,
500
uInt32 xorig, uInt32 yorig, int color)
590
void FBSurfaceSoft::drawChar(const GUI::Font* font, uInt8 chr,
591
uInt32 tx, uInt32 ty, uInt32 color)
502
593
const FontDesc& desc = font->desc();
507
598
if (chr == ' ') return;
508
599
chr = desc.defaultchar;
511
const Int32 w = font->getCharWidth(chr);
512
const Int32 h = font->getFontHeight();
513
601
chr -= desc.firstchar;
514
const uInt32* tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * h));
516
// Scale the origins to the current zoom
517
xorig *= myZoomLevel;
518
yorig *= myZoomLevel;
520
SDL_LockSurface(myScreen);
523
switch(myBytesPerPixel)
603
// Get the bounding box of the character
604
int bbw, bbh, bbx, bby;
614
bbw = desc.bbx[chr].w;
615
bbh = desc.bbx[chr].h;
616
bbx = desc.bbx[chr].x;
617
bby = desc.bbx[chr].y;
620
const uInt16* tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.fbbh));
621
switch(myFB.myBytesPerPixel)
527
625
// Get buffer position where upper-left pixel of the character will be drawn
528
uInt16* buffer = (uInt16*) myScreen->pixels + myBaseOffset + yorig * myPitch + xorig;
529
for(int y = h; y; --y)
626
uInt16* buffer = (uInt16*)getBasePtr(tx + bbx, ty + desc.ascent - bby - bbh);
628
for(int y = 0; y < bbh; y++)
531
const uInt32 fontbuf = *tmp++;
532
int ystride = myZoomLevel;
537
uInt32 mask = 0x80000000;
538
int pos = screenofsY;
539
for(int x = 0; x < w; x++, mask >>= 1)
541
int xstride = myZoomLevel;
542
if((fontbuf & mask) != 0)
544
buffer[pos++] = myDefPalette[color];
549
screenofsY += myPitch;
630
const uInt16 ptr = *tmp++;
631
uInt16 mask = 0x8000;
633
for(int x = 0; x < bbw; x++, mask >>= 1)
635
buffer[x] = (uInt16) myFB.myDefPalette[color];
556
643
// Get buffer position where upper-left pixel of the character will be drawn
557
uInt8* buffer = (uInt8*) myScreen->pixels + myBaseOffset + yorig * myPitch + xorig;
558
uInt32 pixel = myDefPalette[color];
559
uInt8 r = (pixel & myFormat->Rmask) >> myFormat->Rshift;
560
uInt8 g = (pixel & myFormat->Gmask) >> myFormat->Gshift;
561
uInt8 b = (pixel & myFormat->Bmask) >> myFormat->Bshift;
563
for(int y = h; y; --y)
644
uInt8* buffer = (uInt8*)getBasePtr(tx + bbx, ty + desc.ascent - bby - bbh);
646
uInt8 a = myFB.myDefPalette24[color][0],
647
b = myFB.myDefPalette24[color][1],
648
c = myFB.myDefPalette24[color][2];
650
for(int y = 0; y < bbh; y++, buffer += myPitch)
565
const uInt32 fontbuf = *tmp++;
566
int ystride = myZoomLevel;
652
const uInt16 ptr = *tmp++;
653
uInt16 mask = 0x8000;
655
uInt8* buf_ptr = buffer;
656
for(int x = 0; x < bbw; x++, mask >>= 1)
571
uInt32 mask = 0x80000000;
572
int pos = screenofsY;
573
for(int x = 0; x < w; x++, mask >>= 1)
575
int xstride = myZoomLevel;
576
if((fontbuf & mask) != 0)
580
buffer[pos++] = r; buffer[pos++] = g; buffer[pos++] = b;
584
pos += xstride + xstride + xstride;
660
*buf_ptr++ = a; *buf_ptr++ = b; *buf_ptr++ = c;
587
screenofsY += myPitch;
594
670
// Get buffer position where upper-left pixel of the character will be drawn
595
uInt32* buffer = (uInt32*) myScreen->pixels + myBaseOffset + yorig * myPitch + xorig;
596
for(int y = h; y; --y)
671
uInt32* buffer = (uInt32*)getBasePtr(tx + bbx, ty + desc.ascent - bby - bbh);
672
for(int y = 0; y < bbh; y++, buffer += myPitch)
598
const uInt32 fontbuf = *tmp++;
599
int ystride = myZoomLevel;
604
uInt32 mask = 0x80000000;
605
int pos = screenofsY;
606
for(int x = 0; x < w; x++, mask >>= 1)
608
int xstride = myZoomLevel;
609
if((fontbuf & mask) != 0)
611
buffer[pos++] = myDefPalette[color];
616
screenofsY += myPitch;
674
const uInt16 ptr = *tmp++;
675
uInt16 mask = 0x8000;
677
for(int x = 0; x < bbw; x++, mask >>= 1)
679
buffer[x] = (uInt32) myFB.myDefPalette[color];
624
SDL_UnlockSurface(myScreen);
627
688
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
628
void FrameBufferSoft::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig,
689
void FBSurfaceSoft::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
690
uInt32 color, uInt32 h)
632
for(int y = 0; y < h; y++)
693
rect.y = ty + myYOffset;
695
for(uInt32 y = 0; y < h; y++)
697
rect.x = tx + myXOffset;
634
698
uInt32 mask = 0xF0000000;
636
for(int x = 0; x < 8; x++, mask >>= 4)
699
for(uInt32 x = 0; x < 8; x++, mask >>= 4)
638
701
if(bitmap[y] & mask)
640
rect.x = myImageDim.x + (x + xorig) * myZoomLevel;
641
rect.y = myImageDim.y + (y + yorig) * myZoomLevel;
642
rect.w = rect.h = myZoomLevel;
643
SDL_FillRect(myScreen, &rect, myDefPalette[color]);
702
SDL_FillRect(mySurface, &rect, myFB.myDefPalette[color]);
649
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
650
void FrameBufferSoft::drawSurface(const GUI::Surface* surface, Int32 x, Int32 y)
710
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
711
void FBSurfaceSoft::drawPixels(uInt32* data, uInt32 tx, uInt32 ty,
715
rect.x = tx + myXOffset;
716
rect.y = ty + myYOffset;
718
for(uInt32 x = 0; x < numpixels; ++x)
720
SDL_FillRect(mySurface, &rect, data[x]);
725
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
726
void FBSurfaceSoft::drawSurface(const FBSurface* surface, uInt32 tx, uInt32 ty)
728
const FBSurfaceSoft* s = (const FBSurfaceSoft*) surface;
652
730
SDL_Rect dstrect;
653
dstrect.x = x * myZoomLevel + myImageDim.x;
654
dstrect.y = y * myZoomLevel + myImageDim.y;
731
dstrect.x = tx + myXOffset;
732
dstrect.y = ty + myYOffset;
655
733
SDL_Rect srcrect;
658
srcrect.w = surface->myClipWidth * myZoomLevel;
659
srcrect.h = surface->myClipHeight * myZoomLevel;
661
SDL_BlitSurface(surface->myData, &srcrect, myScreen, &dstrect);
664
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
665
void FrameBufferSoft::bytesToSurface(GUI::Surface* surface, int row,
666
uInt8* data, int rowbytes) const
668
// Calculate a scanline of zoomed surface data
669
SDL_Surface* s = surface->myData;
672
rect.y = row * myZoomLevel;
673
for(int c = 0; c < rowbytes; c += 3)
675
uInt32 pixel = SDL_MapRGB(s->format, data[c], data[c+1], data[c+2]);
676
rect.x += myZoomLevel;
677
rect.w = rect.h = myZoomLevel;
678
SDL_FillRect(surface->myData, &rect, pixel);
682
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
683
void FrameBufferSoft::translateCoords(Int32& x, Int32& y) const
685
x = (x - myImageDim.x) / myZoomLevel;
686
y = (y - myImageDim.y) / myZoomLevel;
689
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
690
void FrameBufferSoft::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
692
// Add a dirty rect to the UI rectangle list
693
// TODO - intelligent merging of rectangles, to avoid overlap
696
temp.x = myImageDim.x + x * myZoomLevel;
697
temp.y = myImageDim.y + y * myZoomLevel;
698
temp.w = w * myZoomLevel;
699
temp.h = h * myZoomLevel;
703
temp.w = myScreenDim.w;
704
temp.h = myScreenDim.h;
706
myRectList->add(&temp);
708
// cerr << "addDirtyRect(): "
709
// << "x=" << temp.x << ", y=" << temp.y << ", w=" << temp.w << ", h=" << temp.h << endl;
712
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
713
void FrameBufferSoft::enablePhosphor(bool enable, int blend)
715
myUsePhosphor = enable;
716
myPhosphorBlend = blend;
718
stateChanged(myOSystem->eventHandler().state());
721
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
722
void FrameBufferSoft::stateChanged(EventHandler::State state)
727
myInUIMode = (state == EventHandler::S_LAUNCHER ||
728
state == EventHandler::S_DEBUGGER);
730
// Make sure drawMediaSource() knows which renderer to use
731
switch(myBytesPerPixel)
736
srcrect.w = s->myWidth;
737
srcrect.h = s->myHeight;
739
SDL_BlitSurface(s->mySurface, &srcrect, mySurface, &dstrect);
742
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
743
void FBSurfaceSoft::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
745
//cerr << " -> addDirtyRect: x = " << x << ", y = " << y << ", w = " << w << ", h = " << h << endl;
747
// Base surfaces use dirty-rectangle updates, since they can be quite
748
// large, and updating the entire surface each frame would be too slow
749
// Non-base surfaces are usually smaller, and can be updated entirely
752
// Add a dirty rect to the UI rectangle list
753
// TODO - intelligent merging of rectangles, to avoid overlap
755
temp.x = x + myXOrig; temp.y = y + myYOrig; temp.w = w; temp.h = h;
756
myFB.myRectList->add(&temp);
761
temp.x = myXOrig; temp.y = myYOrig; temp.w = myWidth; temp.h = myHeight;
762
myFB.myRectList->add(&temp);
764
// Indicate that at least one dirty rect has been added
765
// This is an optimization for the update() method
766
mySurfaceIsDirty = true;
770
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
771
void FBSurfaceSoft::getPos(uInt32& x, uInt32& y) const
773
// Return the origin of the 'usable' area of a surface
786
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
787
void FBSurfaceSoft::setPos(uInt32 x, uInt32 y)
794
myXOffset = myFB.imageRect().x();
795
myYOffset = myFB.imageRect().y();
799
myXOffset = myYOffset = 0;
803
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
804
void FBSurfaceSoft::setWidth(uInt32 w)
809
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
810
void FBSurfaceSoft::setHeight(uInt32 h)
815
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
816
void FBSurfaceSoft::translateCoords(Int32& x, Int32& y) const
822
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
823
void FBSurfaceSoft::update()
825
// Since this method is called each frame, we only blit the surfaces when
826
// absolutely necessary
827
if(mySurfaceIsDirty /* && !myIsBaseSurface */)
833
srcrect.h = myHeight;
839
dstrect.h = myHeight;
841
SDL_BlitSurface(mySurface, &srcrect, myFB.myScreen, &dstrect);
842
mySurfaceIsDirty = false;
846
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
847
void FBSurfaceSoft::reload()
849
switch(mySurface->format->BytesPerPixel)
733
851
case 2: // 16-bit
734
myPitch = myScreen->pitch/2;
736
myRenderType = kPhosphor_16;
738
myRenderType = kSoftZoom_16;
852
myPitch = mySurface->pitch >> 1;
740
854
case 3: // 24-bit
741
myPitch = myScreen->pitch;
743
myRenderType = kPhosphor_24;
745
myRenderType = kSoftZoom_24;
855
myPitch = mySurface->pitch;
747
857
case 4: // 32-bit
748
myPitch = myScreen->pitch/4;
750
myRenderType = kPhosphor_32;
752
myRenderType = kSoftZoom_32;
755
myRenderType = kSoftZoom_16; // What else should we do here?
858
myPitch = mySurface->pitch >> 2;
759
// Have the changes take effect
760
myOSystem->eventHandler().refreshDisplay();
763
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
764
GUI::Surface* FrameBufferSoft::createSurface(int width, int height) const
767
SDL_CreateRGBSurface(SDL_SWSURFACE, width*myZoomLevel, height*myZoomLevel,
768
myBytesPerPixel << 3, myFormat->Rmask, myFormat->Gmask,
769
myFormat->Bmask, myFormat->Amask);
771
return data ? new GUI::Surface(width, height, data) : NULL;