Root/src/surface.cpp

1/***************************************************************************
2 * Copyright (C) 2006 by Massimiliano Torromeo *
3 * massimiliano.torromeo@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program 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 *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21#include "surface.h"
22#include "imageio.h"
23#include "utilities.h"
24#include "debug.h"
25#include "surfacecollection.h"
26
27#include <SDL_gfxPrimitives.h>
28
29#include <iostream>
30using namespace std;
31
32RGBAColor strtorgba(const string &strColor) {
33    RGBAColor c = {0,0,0,255};
34    c.r = constrain( strtol( strColor.substr(0,2).c_str(), NULL, 16 ), 0, 255 );
35    c.g = constrain( strtol( strColor.substr(2,2).c_str(), NULL, 16 ), 0, 255 );
36    c.b = constrain( strtol( strColor.substr(4,2).c_str(), NULL, 16 ), 0, 255 );
37    c.a = constrain( strtol( strColor.substr(6,2).c_str(), NULL, 16 ), 0, 255 );
38    return c;
39}
40
41Surface::Surface() {
42    raw = NULL;
43    dblbuffer = NULL;
44}
45
46Surface::Surface(Surface *s) {
47    dblbuffer = NULL;
48    raw = SDL_DisplayFormat(s->raw);
49    halfW = raw->w/2;
50    halfH = raw->h/2;
51}
52
53Surface::Surface(const string &img, const string &skin) {
54    raw = NULL;
55    dblbuffer = NULL;
56    load(img, skin);
57    halfW = raw->w/2;
58    halfH = raw->h/2;
59}
60
61Surface::~Surface() {
62    free();
63}
64
65void Surface::enableVirtualDoubleBuffer(SDL_Surface *surface) {
66    dblbuffer = surface;
67    raw = SDL_DisplayFormat(dblbuffer);
68}
69
70void Surface::free() {
71    if (raw!=NULL) SDL_FreeSurface( raw );
72    if (dblbuffer!=NULL) SDL_FreeSurface( dblbuffer );
73}
74
75SDL_PixelFormat *Surface::format() {
76    if (raw==NULL)
77        return NULL;
78    else
79        return raw->format;
80}
81
82void Surface::load(const string &img, const string &skin) {
83    free();
84
85    string skinpath;
86    if (!skin.empty() && !img.empty() && img[0]!='/')
87      skinpath = SurfaceCollection::getSkinFilePath(skin, img);
88    else
89      skinpath = img;
90
91    raw = loadPNG(skinpath);
92    if (!raw) {
93        ERROR("Couldn't load surface '%s'\n", img.c_str());
94    }
95}
96
97void Surface::flip() {
98    if (dblbuffer!=NULL) {
99        this->blit(dblbuffer,0,0);
100        SDL_Flip(dblbuffer);
101    } else {
102        SDL_Flip(raw);
103    }
104}
105
106bool Surface::blit(SDL_Surface *destination, int x, int y, int w, int h, int a) {
107    if (destination == NULL || a==0) return false;
108
109    SDL_Rect src = {0,0,w,h};
110    SDL_Rect dest;
111    dest.x = x;
112    dest.y = y;
113    if (a>0 && a!=raw->format->alpha)
114        SDL_SetAlpha(raw, SDL_SRCALPHA|SDL_RLEACCEL, a);
115    return SDL_BlitSurface(raw, (w==0 || h==0) ? NULL : &src, destination, &dest);
116}
117bool Surface::blit(Surface *destination, int x, int y, int w, int h, int a) {
118    return blit(destination->raw,x,y,w,h,a);
119}
120
121bool Surface::blitCenter(SDL_Surface *destination, int x, int y, int w, int h, int a) {
122    int oh, ow;
123    if (w==0) ow = halfW; else ow = min(halfW,w/2);
124    if (h==0) oh = halfH; else oh = min(halfH,h/2);
125    return blit(destination,x-ow,y-oh,w,h,a);
126}
127bool Surface::blitCenter(Surface *destination, int x, int y, int w, int h, int a) {
128    return blitCenter(destination->raw,x,y,w,h,a);
129}
130
131bool Surface::blitRight(SDL_Surface *destination, int x, int y, int w, int h, int a) {
132    if (!w) w = raw->w;
133    return blit(destination,x-min(raw->w,w),y,w,h,a);
134}
135bool Surface::blitRight(Surface *destination, int x, int y, int w, int h, int a) {
136    if (!w) w = raw->w;
137    return blitRight(destination->raw,x,y,w,h,a);
138}
139
140int Surface::box(Sint16 x, Sint16 y, Sint16 w, Sint16 h, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
141    return boxRGBA(raw,x,y,x+w-1,y+h-1,r,g,b,a);
142}
143int Surface::box(Sint16 x, Sint16 y, Sint16 w, Sint16 h, Uint8 r, Uint8 g, Uint8 b) {
144    SDL_Rect re = {x,y,w,h};
145    return SDL_FillRect(raw, &re, SDL_MapRGBA(format(),r,g,b,255));
146}
147int Surface::box(Sint16 x, Sint16 y, Sint16 w, Sint16 h, RGBAColor c) {
148    return box(x,y,w,h,c.r,c.g,c.b,c.a);
149}
150int Surface::box(SDL_Rect re, RGBAColor c) {
151    return boxRGBA(
152        raw, re.x, re.y, re.x + re.w - 1, re.y + re.h - 1, c.r, c.g, c.b, c.a
153        );
154}
155
156int Surface::rectangle(Sint16 x, Sint16 y, Sint16 w, Sint16 h, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
157    return rectangleRGBA(raw,x,y,x+w-1,y+h-1,r,g,b,a);
158}
159int Surface::rectangle(Sint16 x, Sint16 y, Sint16 w, Sint16 h, RGBAColor c) {
160    return rectangle(x,y,w,h,c.r,c.g,c.b,c.a);
161}
162int Surface::rectangle(SDL_Rect re, RGBAColor c) {
163    return rectangle(re.x,re.y,re.w,re.h,c.r,c.g,c.b,c.a);
164}
165
166int Surface::hline(Sint16 x, Sint16 y, Sint16 w, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
167    return hlineRGBA(raw,x,x+w-1,y,r,g,b,a);
168}
169
170void Surface::clearClipRect() {
171    SDL_SetClipRect(raw,NULL);
172}
173
174void Surface::setClipRect(int x, int y, int w, int h) {
175    SDL_Rect rect = {x,y,w,h};
176    setClipRect(rect);
177}
178
179void Surface::setClipRect(SDL_Rect rect) {
180    SDL_SetClipRect(raw,&rect);
181}
182
183bool Surface::blit(Surface *destination, SDL_Rect container, ASFont::HAlign halign, ASFont::VAlign valign) {
184    switch (halign) {
185    case ASFont::HAlignLeft:
186        break;
187    case ASFont::HAlignCenter:
188        container.x += container.w/2-halfW;
189        break;
190    case ASFont::HAlignRight:
191        container.x += container.w-raw->w;
192        break;
193    }
194
195    switch (valign) {
196    case ASFont::VAlignTop:
197        break;
198    case ASFont::VAlignMiddle:
199        container.y += container.h/2-halfH;
200        break;
201    case ASFont::VAlignBottom:
202        container.y += container.h-raw->h;
203        break;
204    }
205
206    return blit(destination,container.x,container.y);
207}
208

Archive Download this file



interactive