~gunchleoc/widelands/bug-1818494-ingame-zoom-freezes

« back to all changes in this revision

Viewing changes to src/graphic.cc

  • Committer: sirver
  • Date: 2002-02-05 20:54:08 UTC
  • Revision ID: git-v1:df384fd3a5e53be1f37803d1c0381fa993844bf5
Initial revision


git-svn-id: https://widelands.svn.sourceforge.net/svnroot/widelands/trunk@2 37b2a8de-5219-0410-9f54-a31bc463ab9c

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2001 by Holger Rapp 
 
3
 * 
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 * 
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 * 
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 *
 
18
 */
 
19
 
 
20
#include "graphic.h"
 
21
 
 
22
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
23
 
 
24
namespace Graph {
 
25
 
 
26
                  /** class Graphic
 
27
                        *
 
28
                        * This functions is responsible for displaying graphics and keeping them up to date
 
29
                        *
 
30
                        * It's little strange in it's interface, but it is optimzed for speed, not beauty
 
31
                        * This is a singleton
 
32
                        */
 
33
 
 
34
                  /** Graphic::Graphic(void) 
 
35
                        *
 
36
                        * Default Constructor. Simple Inits
 
37
                        *
 
38
                        * Args: none
 
39
                        * Returns: nothing
 
40
                        */
 
41
                  Graphic::Graphic(void) {
 
42
                                         lpix=0;
 
43
                                         sc=NULL;
 
44
                                         pixels=NULL;
 
45
                                         xres=yres=0;
 
46
                                         st=NOT_INIT;
 
47
                                         bis_fs=0;
 
48
 
 
49
                                         SDL_Init(SDL_INIT_VIDEO);
 
50
                  }
 
51
 
 
52
                  /** Graphic::~Graphic(void) 
 
53
                        *
 
54
                        * simple cleanups. 
 
55
                        *
 
56
                        * Args: none
 
57
                        * Returns: nothing
 
58
                        */
 
59
                  Graphic::~Graphic(void) {
 
60
                                         lpix=0;
 
61
                                         if(sc) {
 
62
                                                                SDL_FreeSurface(sc);
 
63
                                                                sc=NULL;
 
64
                                         }
 
65
                                         pixels=NULL;
 
66
                                         xres=yres=0;
 
67
                                         st=NOT_INIT;
 
68
 
 
69
                                         SDL_Quit();
 
70
                  }
 
71
 
 
72
                  /** void Graphic::set_mode(const unsigned short x, const unsigned short y, const Mode m)
 
73
                        *
 
74
                        * This function sets a new graphics mode.
 
75
                        *
 
76
                        * Args: x       x resolution
 
77
                        *               y       y resolution
 
78
                        *               m       either windows or fullscreen
 
79
                        * Returns: Nothing
 
80
                        */
 
81
                  void Graphic::set_mode(const unsigned short x, const unsigned short y, const Mode m) {
 
82
                                         if(sc)
 
83
                                                                SDL_FreeSurface(sc);
 
84
 
 
85
                                         if(m==MODE_FS) {
 
86
                                                                sc = SDL_SetVideoMode(x, y, 16, SDL_SWSURFACE | SDL_FULLSCREEN);
 
87
                                                                bis_fs=1;
 
88
                                         } else {
 
89
                                                                sc = SDL_SetVideoMode(x, y, 16, SDL_SWSURFACE);
 
90
                                                                bis_fs=0;
 
91
                                         }
 
92
 
 
93
                                         xres=x; 
 
94
                                         yres=y;
 
95
                                         pixels=(unsigned short*) sc->pixels;
 
96
 
 
97
                                         st=OK;
 
98
 
 
99
                                         return;
 
100
                  }
 
101
 
 
102
                  /** void Graphic::update_screen(void);
 
103
                        * 
 
104
                        * This updates the whole screen
 
105
                        *
 
106
                        * Args: None
 
107
                        * Returns: Nothing
 
108
                        */
 
109
                  void Graphic::update_screen(void) {
 
110
                                         if(!sc) {
 
111
                                                                st=ERROR;
 
112
                                                                return;
 
113
                                         }
 
114
 
 
115
                                         SDL_UpdateRect(sc, 0, 0, xres, yres);
 
116
                  }
 
117
                  
 
118
                  /** void Graphic::update_rect(const unsigned short x, const unsigned short y, const unsigned short w, const unsigned short h);
 
119
                        *
 
120
                        * This updates a rect of the screen
 
121
                        *
 
122
                        * Args:         x       upper left corner of rect
 
123
                        *                       y  upper left corner of rect
 
124
                        *                       w       width
 
125
                        *                       h       height
 
126
                        */
 
127
                  void Graphic::update_rect(const unsigned short x, const unsigned short y, const unsigned short w, const unsigned short h) {
 
128
                                         if(!sc) {
 
129
                                                                st=ERROR;
 
130
                                                                return;
 
131
                                         }
 
132
 
 
133
                                         SDL_UpdateRect(sc, x, y, w, h);
 
134
                  }
 
135
 
 
136
                  /** void Graphic::update_quarter(void) 
 
137
                        *
 
138
                        * This function updates a bit of the screen, but this bit moves around each time
 
139
                        * this function gets called. 
 
140
                        * So it's made sure, that the whole screen gets updated, when this function gets called
 
141
                        * every frame
 
142
                        *
 
143
                        * Args: none
 
144
                        * Returns: Nothing
 
145
                        */
 
146
                  void Graphic::update_quarter(void) {
 
147
                                        static unsigned int x; 
 
148
                                        static unsigned int y;
 
149
                                        static unsigned int xadd=xres/4;
 
150
                                        static unsigned int yadd=yres/4;
 
151
 
 
152
                                        if(x==xres) { x=0; y+=yadd; }
 
153
                                        if(y==yres) y=0;
 
154
 
 
155
                                        SDL_UpdateRect(sc, x, y, xadd, yadd);
 
156
                                        x+=xadd;
 
157
                  }
 
158
                  
 
159
                  /** void draw_pic(Pic* p, const unsigned short d_x_pos, const unsigned short d_y_pos,  const unsigned short p_x_pos, 
 
160
                        *               const unsigned short p_y_pos, const unsigned short i_w, const unsigned short i_h)
 
161
                        *
 
162
                        *       This functions plots a picture onto the current screen
 
163
                        *       
 
164
                        *       friend to class pic and class Graphic
 
165
                        *
 
166
                        *       Args:   p       picture to plot
 
167
                        *                       d_x_pos xpos on screen
 
168
                        *                       d_y_pos ypos on screen
 
169
                        *                       p_x_pos start xpos in picture
 
170
                        *                       p_y_pos start ypos in picture
 
171
                        *                       i_w             width
 
172
                        *                       i_h             height
 
173
                        *       returns: Nothing
 
174
                        */
 
175
                  void draw_pic(Pic* p, const unsigned short d_x_pos, const unsigned short d_y_pos,  const unsigned short p_x_pos, const unsigned short p_y_pos, 
 
176
                                                                const unsigned short i_w, const unsigned short i_h) {
 
177
                                         unsigned short clr;
 
178
                                         unsigned short w=i_w;
 
179
                                         unsigned short h=i_h; 
 
180
 
 
181
                                         if(d_x_pos+w>g_gr.get_xres()) w=g_gr.get_xres()-d_x_pos;
 
182
                                         if(d_y_pos+h>g_gr.get_yres()) h=g_gr.get_yres()-d_y_pos;
 
183
 
 
184
                                         if(p->has_clrkey()) {
 
185
                                                                // Slow blit, checking for clrkeys. This could probably speed up by copying
 
186
                                                                // 2 pixels (==4bytes==register width)
 
187
                                                                // in one rush. But this is a nontrivial task
 
188
                                                                for(unsigned long  y=0; y<h; y++) {
 
189
                                                                                  clr=p->get_pixel(p_x_pos, p_y_pos+y);
 
190
                                                                                  if(clr != p->get_clrkey()) g_gr.set_pixel(d_x_pos, d_y_pos+y, clr);
 
191
                                                                                  else g_gr.set_cpixel(d_x_pos, d_y_pos+y);
 
192
                                                                                  for(unsigned long x=1; x<w; x++) {
 
193
                                                                                                         clr=p->get_npixel();
 
194
                                                                                                         if(clr != p->get_clrkey()) g_gr.set_npixel(clr);
 
195
                                                                                                         else g_gr.npixel();
 
196
                                                                                  }
 
197
                                                                }
 
198
                                         } else {
 
199
                                                                unsigned long poffs=p->get_w()*p_y_pos + p_x_pos;
 
200
                                                                unsigned long doffs=g_gr.get_xres()*d_y_pos + d_x_pos;
 
201
 
 
202
                                                                // fast blitting, using memcpy
 
203
                                                                for(unsigned long y=0; y<h; y++) {
 
204
                                                                                  memcpy(g_gr.pixels+doffs, p->pixels+poffs, w<<1); // w*sizeof(short) 
 
205
                                                                                  doffs+=g_gr.get_xres();
 
206
                                                                                  poffs+=p->get_w();
 
207
                                                                }
 
208
                                         }
 
209
                  }
 
210
                                                                                                
 
211
                  /** void copy_pic(Pic* dst, Pic* src, const unsigned short d_x_pos, const unsigned short d_y_pos,  const unsigned short p_x_pos, 
 
212
                        *               const unsigned short p_y_pos, const unsigned short i_w, const unsigned short i_h)
 
213
                        *
 
214
                        *       This functions plots a picture into an other
 
215
                        *
 
216
                        *       friend to class pic
 
217
                        *
 
218
                        *       Args:   src     picture to plot
 
219
                        *                       dst     picture to plot inside
 
220
                        *                       d_x_pos xpos on screen
 
221
                        *                       d_y_pos ypos on screen
 
222
                        *                       p_x_pos start xpos in picture
 
223
                        *                       p_y_pos start ypos in picture
 
224
                        *                       i_w             width
 
225
                        *                       i_h             height
 
226
                        *       returns: Nothing
 
227
                        */
 
228
                  void copy_pic(Pic* dst, Pic* src, const unsigned short d_x_pos, const unsigned short d_y_pos,  const unsigned short p_x_pos, 
 
229
                                                                const unsigned short p_y_pos, const unsigned short i_w, const unsigned short i_h) {
 
230
                                         unsigned short clr;
 
231
                                         unsigned short w=i_w;
 
232
                                         unsigned short h=i_h; 
 
233
 
 
234
                                         if(d_x_pos+w>g_gr.get_xres()) w=g_gr.get_xres()-d_x_pos;
 
235
                                         if(d_y_pos+h>g_gr.get_yres()) h=g_gr.get_yres()-d_y_pos;
 
236
 
 
237
                                         if(src->has_clrkey() && (dst->get_clrkey()!=src->get_clrkey())) {
 
238
                                                                for(unsigned long  y=0; y<h; y++) {
 
239
                                                                                  clr=src->get_pixel(p_x_pos, p_y_pos+y);
 
240
                                                                                  dst->set_pixel(d_x_pos, d_y_pos+y, clr);
 
241
                                                                                  for(unsigned long x=1; x<w; x++) {
 
242
                                                                                                         clr=src->get_npixel();
 
243
                                                                                                         dst->set_npixel(clr);
 
244
                                                                                  }
 
245
                                                                }
 
246
                                         } else {
 
247
                                                                unsigned long soffs=src->get_w()*p_y_pos + p_x_pos;
 
248
                                                                unsigned long doffs=dst->get_w()*d_y_pos + d_x_pos;
 
249
 
 
250
                                                                // fast blitting, using memcpy
 
251
                                                                for(unsigned long y=0; y<h; y++) {
 
252
                                                                                  memcpy(dst->pixels+doffs, src->pixels+soffs, w<<1); // w*sizeof(short) 
 
253
                                                                                  doffs+=dst->get_w();
 
254
                                                                                  soffs+=src->get_w();
 
255
                                                                }
 
256
                                         }                
 
257
                  }
 
258
}