00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <cassert>
00023
00024 #include "graphics.h"
00025 #include "log.h"
00026
00027 #include "resources/image.h"
00028 #include "resources/imageloader.h"
00029
00030 Graphics::Graphics():
00031 mScreen(0)
00032 {
00033 }
00034
00035 Graphics::~Graphics()
00036 {
00037 _endDraw();
00038 }
00039
00040 bool Graphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
00041 {
00042 logger->log("Setting video mode %dx%d %s",
00043 w, h, fs ? "fullscreen" : "windowed");
00044
00045 logger->log("Bits per pixel: %d", bpp);
00046
00047 int displayFlags = SDL_ANYFORMAT;
00048
00049 mFullscreen = fs;
00050 mHWAccel = hwaccel;
00051
00052 if (fs)
00053 displayFlags |= SDL_FULLSCREEN;
00054
00055 if (hwaccel)
00056 displayFlags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
00057 else
00058 displayFlags |= SDL_SWSURFACE;
00059
00060 mScreen = SDL_SetVideoMode(w, h, bpp, displayFlags);
00061
00062 if (!mScreen)
00063 return false;
00064
00065 char videoDriverName[64];
00066
00067 if (SDL_VideoDriverName(videoDriverName, 64))
00068 logger->log("Using video driver: %s", videoDriverName);
00069 else
00070 logger->log("Using video driver: unknown");
00071
00072 const SDL_VideoInfo *vi = SDL_GetVideoInfo();
00073
00074 logger->log("Possible to create hardware surfaces: %s",
00075 ((vi->hw_available) ? "yes" : "no"));
00076 logger->log("Window manager available: %s",
00077 ((vi->wm_available) ? "yes" : "no"));
00078 logger->log("Accelerated hardware to hardware blits: %s",
00079 ((vi->blit_hw) ? "yes" : "no"));
00080 logger->log("Accelerated hardware to hardware colorkey blits: %s",
00081 ((vi->blit_hw_CC) ? "yes" : "no"));
00082 logger->log("Accelerated hardware to hardware alpha blits: %s",
00083 ((vi->blit_hw_A) ? "yes" : "no"));
00084 logger->log("Accelerated software to hardware blits: %s",
00085 ((vi->blit_sw) ? "yes" : "no"));
00086 logger->log("Accelerated software to hardware colorkey blits: %s",
00087 ((vi->blit_sw_CC) ? "yes" : "no"));
00088 logger->log("Accelerated software to hardware alpha blits: %s",
00089 ((vi->blit_sw_A) ? "yes" : "no"));
00090 logger->log("Accelerated color fills: %s",
00091 ((vi->blit_fill) ? "yes" : "no"));
00092 logger->log("Available video memory: %d", vi->video_mem);
00093
00094 setTarget(mScreen);
00095
00096 return true;
00097 }
00098
00099 bool Graphics::setFullscreen(bool fs)
00100 {
00101 if (mFullscreen == fs)
00102 return true;
00103
00104 return setVideoMode(mScreen->w, mScreen->h,
00105 mScreen->format->BitsPerPixel, fs, mHWAccel);
00106 }
00107
00108 int Graphics::getWidth() const
00109 {
00110 return mScreen->w;
00111 }
00112
00113 int Graphics::getHeight() const
00114 {
00115 return mScreen->h;
00116 }
00117
00118 bool Graphics::drawImage(Image *image, int x, int y)
00119 {
00120 return drawImage(image, 0, 0, x, y, image->mBounds.w, image->mBounds.h);
00121 }
00122
00123 bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY,
00124 int width, int height, bool)
00125 {
00126
00127 if (!mScreen || !image || !image->mImage) return false;
00128
00129 dstX += mClipStack.top().xOffset;
00130 dstY += mClipStack.top().yOffset;
00131
00132 srcX += image->mBounds.x;
00133 srcY += image->mBounds.y;
00134
00135 SDL_Rect dstRect;
00136 SDL_Rect srcRect;
00137 dstRect.x = dstX; dstRect.y = dstY;
00138 srcRect.x = srcX; srcRect.y = srcY;
00139 srcRect.w = width;
00140 srcRect.h = height;
00141
00142 return !(SDL_BlitSurface(image->mImage, &srcRect, mScreen, &dstRect) < 0);
00143 }
00144
00145 void Graphics::drawImage(gcn::Image const *image, int srcX, int srcY,
00146 int dstX, int dstY, int width, int height)
00147 {
00148 ProxyImage const *srcImage =
00149 dynamic_cast< ProxyImage const * >(image);
00150 assert(srcImage);
00151 drawImage(srcImage->getImage(), srcX, srcY, dstX, dstY, width, height, true);
00152 }
00153
00154 void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h)
00155 {
00156
00157 if (!mScreen || !image || !image->mImage) return;
00158
00159 const int iw = image->getWidth();
00160 const int ih = image->getHeight();
00161
00162 if (iw == 0 || ih == 0) return;
00163
00164 for (int py = 0; py < h; py += ih)
00165 {
00166 int dh = (py + ih >= h) ? h - py : ih;
00167 int srcY = image->mBounds.y;
00168 int dstY = y + py + mClipStack.top().yOffset;
00169
00170 for (int px = 0; px < w; px += iw)
00171 {
00172 int dw = (px + iw >= w) ? w - px : iw;
00173 int srcX = image->mBounds.x;
00174 int dstX = x + px + mClipStack.top().xOffset;
00175
00176 SDL_Rect dstRect;
00177 SDL_Rect srcRect;
00178 dstRect.x = dstX; dstRect.y = dstY;
00179 srcRect.x = srcX; srcRect.y = srcY;
00180 srcRect.w = dw; srcRect.h = dh;
00181
00182 SDL_BlitSurface(image->mImage, &srcRect, mScreen, &dstRect);
00183 }
00184 }
00185 }
00186
00187 void Graphics::drawImageRect(int x, int y, int w, int h,
00188 Image *topLeft, Image *topRight,
00189 Image *bottomLeft, Image *bottomRight,
00190 Image *top, Image *right,
00191 Image *bottom, Image *left,
00192 Image *center)
00193 {
00194 pushClipArea(gcn::Rectangle(x, y, w, h));
00195
00196
00197 drawImagePattern(center,
00198 topLeft->getWidth(), topLeft->getHeight(),
00199 w - topLeft->getWidth() - topRight->getWidth(),
00200 h - topLeft->getHeight() - bottomLeft->getHeight());
00201
00202
00203 drawImagePattern(top,
00204 left->getWidth(), 0,
00205 w - left->getWidth() - right->getWidth(), top->getHeight());
00206 drawImagePattern(bottom,
00207 left->getWidth(), h - bottom->getHeight(),
00208 w - left->getWidth() - right->getWidth(),
00209 bottom->getHeight());
00210 drawImagePattern(left,
00211 0, top->getHeight(),
00212 left->getWidth(),
00213 h - top->getHeight() - bottom->getHeight());
00214 drawImagePattern(right,
00215 w - right->getWidth(), top->getHeight(),
00216 right->getWidth(),
00217 h - top->getHeight() - bottom->getHeight());
00218
00219
00220 drawImage(topLeft, 0, 0);
00221 drawImage(topRight, w - topRight->getWidth(), 0);
00222 drawImage(bottomLeft, 0, h - bottomLeft->getHeight());
00223 drawImage(bottomRight,
00224 w - bottomRight->getWidth(),
00225 h - bottomRight->getHeight());
00226
00227 popClipArea();
00228 }
00229
00230 void Graphics::drawImageRect(int x, int y, int w, int h,
00231 const ImageRect &imgRect)
00232 {
00233 drawImageRect(x, y, w, h,
00234 imgRect.grid[0], imgRect.grid[2], imgRect.grid[6], imgRect.grid[8],
00235 imgRect.grid[1], imgRect.grid[5], imgRect.grid[7], imgRect.grid[3],
00236 imgRect.grid[4]);
00237 }
00238
00239 void Graphics::updateScreen()
00240 {
00241 SDL_Flip(mScreen);
00242 }
00243
00244 SDL_Surface *Graphics::getScreenshot()
00245 {
00246 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00247 int rmask = 0xff000000;
00248 int gmask = 0x00ff0000;
00249 int bmask = 0x0000ff00;
00250 #else
00251 int rmask = 0x000000ff;
00252 int gmask = 0x0000ff00;
00253 int bmask = 0x00ff0000;
00254 #endif
00255 int amask = 0x00000000;
00256
00257 SDL_Surface *screenshot = SDL_CreateRGBSurface(SDL_SWSURFACE, mScreen->w,
00258 mScreen->h, 24, rmask, gmask, bmask, amask);
00259
00260 SDL_BlitSurface(mScreen, NULL, screenshot, NULL);
00261
00262 return screenshot;
00263 }