Adonthell  0.4
surface.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 1999/2000/2001/2004 Alexandre Courbot
3  Copyright (C) 2016 Kai Sterker
4  Part of the Adonthell Project <http://adonthell.nongnu.org>
5 
6  Adonthell is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  Adonthell is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Adonthell. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 
21 /**
22  * @file surface.cc
23  * @author Alexandre Courbot
24  * @author Kai Sterker
25  *
26  * Defines the surface class.
27  */
28 
29 #include "surface.h"
30 #include "screen.h"
31 
32 #include <iostream>
33 
34 using namespace std;
35 
36 
37 SDL_Rect surface::srcrect;
38 SDL_Rect surface::dstrect;
39 
40 
41 surface::surface (const u_int8 & scale) : drawable ()
42 {
43  scale_ = scale;
44  offset_x_ = 0;
45  is_masked_ = false;
46  mask_changed_ = false;
47  alpha_ = SDL_ALPHA_OPAQUE;
48  alpha_channel_ = false;
49  Surface = NULL;
50  Info = new pixel_info();
51 }
52 
54 {
55  delete Info;
56  if (Surface) SDL_DestroyTexture (Surface);
57 }
58 
59 void surface::set_mask (bool m)
60 {
61  // since SDL textures do not support masking, we need to
62  // convert the masked image into the appropriate RGBA
63  // representation.
64  if (!Surface)
65  {
66  // if there is no surface yet, we will have to apply the
67  // surface conversion later
68  mask_changed_ = true;
69  return;
70  }
71 
72  if (m && !is_masked_)
73  {
74  is_masked_ = true;
75  mask_changed_ = false;
76 
77  SDL_Surface *s1 = to_sw_surface();
78  SDL_Surface *s2 = SDL_CreateRGBSurfaceFrom(NULL, s1->w, s1->h,
79  32, 0, R_MASK, G_MASK, B_MASK, A_MASK);
80 
81  Info->Format = s2->format->format;
82 
83  SDL_Texture *tmp = SDL_CreateTexture (screen::get_renderer(), Info->Format, SDL_TEXTUREACCESS_STREAMING, s1->w, s1->h);
84  if (!tmp) std::cout << "*** surface_sdl::set_mask: " << SDL_GetError() << std::endl;
85 
86  SDL_LockTexture(tmp, NULL, &s2->pixels, &s2->pitch);
87 
88  SDL_SetSurfaceAlphaMod (s1, SDL_ALPHA_OPAQUE);
89  SDL_SetSurfaceBlendMode (s1, SDL_BLENDMODE_NONE);
90  SDL_BlitSurface (s1, NULL, s2, NULL);
91 
92  SDL_UnlockTexture(tmp);
93 
94  SDL_FreeSurface(s1);
95  SDL_FreeSurface(s2);
96  SDL_DestroyTexture(Surface);
97 
98  Surface = tmp;
99  alpha_channel_ = true;
100  }
101 
102  is_masked_ = m;
103 }
104 
105 
106 void surface::set_alpha (u_int8 t, const bool & alpha_channel)
107 {
108  if ((t == 255) && (alpha_ != 255) && Surface)
109  {
110  SDL_SetTextureAlphaMod(Surface, t);
111  SDL_SetTextureBlendMode(Surface, SDL_BLENDMODE_NONE);
112  }
113 
114  else if (!alpha_channel && alpha_channel_ && Surface)
115  {
116  SDL_SetTextureBlendMode(Surface, SDL_BLENDMODE_NONE);
117  }
118 
119  alpha_ = t;
120  alpha_channel_ = alpha_channel || is_masked_;
121 }
122 
123 SDL_Surface *surface::to_sw_surface(SDL_Rect *rect) const
124 {
125  int bpp;
126  SDL_Surface *s;
127  u_int32 rmask, gmask, bmask, amask;
128 
129  lock(rect);
130 
131  SDL_PixelFormatEnumToMasks(Info->Format, &bpp, &rmask, &gmask, &bmask, &amask);
132  if (!rect)
133  {
134  s = SDL_CreateRGBSurfaceFrom(Info->Pixels, length() * scale(), height() * scale(),
135  bpp, Info->Pitch, rmask, gmask, bmask, amask);
136  }
137  else
138  {
139  s = SDL_CreateRGBSurfaceFrom(Info->Pixels, rect->w, rect->h,
140  bpp, Info->Pitch, rmask, gmask, bmask, amask);
141  }
142 
143  if (is_masked_)
144  {
145  u_int32 trans_col = alpha_channel_? SDL_MapRGBA(s->format, 0xFF, 0x00, 0xFF, 0xFF) : SDL_MapRGB(s->format, 0xFF, 0x00, 0xFF);
146  SDL_SetColorKey(s, 1, trans_col);
147  }
148 
149  if (alpha_channel_ || alpha_ != 255)
150  {
151  if (!alpha_channel_ || is_masked_) SDL_SetSurfaceAlphaMod (s, alpha_);
152  SDL_SetSurfaceBlendMode (s, SDL_BLENDMODE_BLEND);
153  }
154 
155  return s;
156 }
157 
159  u_int16 sh, const drawing_area * da_opt,
160  surface * target) const
161 {
162  setup_rects (x, y, sx, sy, sl, sh, da_opt);
163 
164  if (!dstrect.w || !dstrect.h)
165  return;
166 
167  if (!target || target == &screen::display)
168  {
169  // blit to screen surface (--> hardware accelerated)
170  if (alpha_channel_ || alpha_ != 255)
171  {
172  if (!alpha_channel_ || is_masked_) SDL_SetTextureAlphaMod(Surface, alpha_);
173  SDL_SetTextureBlendMode(Surface, SDL_BLENDMODE_BLEND);
174  }
175 
176  if (scale() > 1)
177  {
178  srcrect.x *= scale();
179  srcrect.y *= scale();
180  srcrect.w *= scale();
181  srcrect.h *= scale();
182  }
183 
184  if (screen::scale() > 1)
185  {
186  dstrect.x = dstrect.x * screen::scale() + screen::offset_x();
187  dstrect.y = dstrect.y * screen::scale() + screen::offset_y();
188  dstrect.w *= screen::scale();
189  dstrect.h *= screen::scale();
190  }
191 
192  SDL_RenderCopy (screen::get_renderer(), Surface, &srcrect, &dstrect);
193  }
194  else
195  {
196  // make sure the drawing target uses the same scale
197  if (target->scale() != scale())
198  {
199  target->set_scale(scale());
200  }
201 
202  if (scale() > 1)
203  {
204  srcrect.x *= scale();
205  srcrect.y *= scale();
206  srcrect.w *= scale();
207  srcrect.h *= scale();
208 
209  dstrect.x = dstrect.x * scale() + target->offset_x_;
210  dstrect.y *= scale();
211  dstrect.w *= scale();
212  dstrect.h *= scale();
213 
214  if (dstrect.x < 0) dstrect.x = 0;
215  if (dstrect.y < 0) dstrect.y = 0;
216  }
217 
218  // make sure we only update the part of the target texture that is actually changed
219  if (dstrect.x + dstrect.w > target->length() * scale()) dstrect.w = target->length() * scale() - dstrect.x;
220  if (dstrect.y + dstrect.h > target->height() * scale()) dstrect.h = target->height() * scale() - dstrect.y;
221  if (dstrect.w <= 0 || dstrect.h <= 0) return;
222 
223  srcrect.w = dstrect.w;
224  srcrect.h = dstrect.h;
225 
226  // blit from one surface to another (--> needs to be in software)
227  SDL_Surface *source_surf = to_sw_surface ();
228  SDL_Surface *target_surf = target->to_sw_surface (&dstrect);
229 
230  SDL_BlitSurface (source_surf, &srcrect, target_surf, NULL);
231 
232  target->unlock();
233 
234  SDL_FreeSurface(source_surf);
235  SDL_FreeSurface(target_surf);
236  }
237 }
238 
240  drawing_area * da_opt)
241 {
242  if (da_opt)
243  {
244  SDL_Rect da = da_opt->setup_rects ();
245  dstrect.x = da.x;
246  dstrect.y = da.y;
247  dstrect.w = da.w;
248  dstrect.h = da.h;
249  }
250  else
251  {
252  dstrect.x = x;
253  dstrect.y = y;
254  dstrect.w = l;
255  dstrect.h = h;
256  }
257 
258  if (this == &screen::display)
259  {
260  u_int8 r, g, b, a;
261  unmap_color(col, r, g, b, a);
262 
263  if (screen::scale() > 1)
264  {
265  dstrect.x = dstrect.x * screen::scale() + screen::offset_x();
266  dstrect.y = dstrect.y * screen::scale() + screen::offset_y();
267  dstrect.w *= screen::scale();
268  dstrect.h *= screen::scale();
269  }
270 
271  SDL_SetRenderDrawBlendMode(screen::get_renderer(), SDL_BLENDMODE_NONE);
272  SDL_SetRenderDrawColor(screen::get_renderer(), r, g, b, a);
273  SDL_RenderFillRect(screen::get_renderer(), &dstrect);
274  }
275  else
276  {
277  if (is_masked_ && col == screen::trans_col())
278  {
279  col = map_color(255, 0, 255, SDL_ALPHA_TRANSPARENT);
280  }
281 
282  if (scale() > 1)
283  {
284  dstrect.x = dstrect.x * scale() + offset_x_;
285  dstrect.y *= scale();
286  dstrect.w *= scale();
287  dstrect.h *= scale();
288 
289  if (dstrect.x < 0) dstrect.x = 0;
290  }
291 
292  if (dstrect.x + dstrect.w > length() * scale()) dstrect.w = length() * scale() - dstrect.x;
293  if (dstrect.y + dstrect.h > height() * scale()) dstrect.h = height() * scale() - dstrect.y;
294  if (dstrect.w <= 0 || dstrect.h <= 0) return;
295 
296  lock(&dstrect);
297 
298  u_int32 *src = new u_int32[dstrect.w * dstrect.h];
299  std::fill_n(src, dstrect.w * dstrect.h, col);
300 
301  SDL_ConvertPixels (dstrect.w, dstrect.h,
302  SDL_PIXELFORMAT_ARGB8888, (const void*) src, dstrect.w*4,
303  Info->Format, Info->Pixels, Info->Pitch);
304 
305  delete[] src;
306  unlock();
307  }
308 }
309 
310 // convert RGBA color to surface format
311 u_int32 surface::map_color (const u_int8 & r, const u_int8 & g, const u_int8 & b, const u_int8 & a) const
312 {
313  return (a << 24) | (r << 16) | (g << 8) | b;
314 }
315 
316 // convert surface color format into RGBA
317 void surface::unmap_color(u_int32 col, u_int8 & r, u_int8 & g, u_int8 & b, u_int8 & a) const
318 {
319  a = (col & 0xFF000000) >> 24;
320  r = (col & 0x00FF0000) >> 16;
321  g = (col & 0x0000FF00) >> 8;
322  b = (col & 0x000000FF);
323 }
324 
325 void surface::lock (SDL_Rect *rect) const
326 {
327  if (!length () || !height ()) return;
328 
329  if (this != &screen::display)
330  {
331  SDL_LockTexture (Surface, rect, &Info->Pixels, &Info->Pitch);
332  Info->BytesPerPixel = SDL_BYTESPERPIXEL(Info->Format);
333  }
334 }
335 
336 void surface::unlock () const
337 {
338  if (!length () || !height ()) return;
339 
340  if (Info->Pixels)
341  {
342  SDL_UnlockTexture (Surface);
343  Info->Pixels = NULL;
344  }
345 }
346 
348 {
349  u_int8 r, g, b, a;
350 
351  if (this == &screen::display)
352  {
353  unmap_color(col, r, g, b, a);
354 
355  if (screen::scale() > 1)
356  {
357  fillrect(x, y, 1, 1, col);
358  return;
359  }
360 
361  x += screen::offset_x();
362  y += screen::offset_y();
363 
364  SDL_SetRenderDrawBlendMode(screen::get_renderer(), SDL_BLENDMODE_NONE);
365  SDL_SetRenderDrawColor(screen::get_renderer(), r, g, b, a);
366  SDL_RenderDrawPoint(screen::get_renderer(), x, y);
367  return;
368  }
369 
370  if (!Info->Pixels) return;
371 
372  u_int8 *offset = ((Uint8 *) Info->Pixels) + y * Info->Pitch + x * Info->BytesPerPixel;
373 
374  if (!alpha_channel_)
375  {
376  unmap_color(col, r, g, b, a);
377 
378  switch (Info->Format)
379  {
380  case SDL_PIXELFORMAT_RGB24:
381  *(offset) = r;
382  *(++offset) = g;
383  *(++offset) = b;
384  break;
385  case SDL_PIXELFORMAT_BGR24:
386  *(offset) = b;
387  *(++offset) = g;
388  *(++offset) = r;
389  break;
390  }
391  return;
392  }
393 
394 #ifdef __BIG_ENDIAN__
395  unmap_color(col, b, a, g, r);
396 #else
397  unmap_color(col, r, g, b, a);
398 #endif
399 
400  switch (Info->Format)
401  {
402  case SDL_PIXELFORMAT_BGR888:
403  *(++offset) = r;
404  *(++offset) = g;
405  *(++offset) = b;
406  break;
407  case SDL_PIXELFORMAT_RGBA8888:
408  *(offset) = a;
409  *(++offset) = r;
410  *(++offset) = g;
411  *(++offset) = b;
412  break;
413  case SDL_PIXELFORMAT_ARGB8888:
414  *(offset) = r;
415  *(++offset) = g;
416  *(++offset) = b;
417  *(++offset) = a;
418  break;
419  case SDL_PIXELFORMAT_RGB888:
420  *(++offset) = b;
421  *(++offset) = g;
422  *(++offset) = r;
423  break;
424  case SDL_PIXELFORMAT_ABGR8888:
425  *(offset) = b;
426  *(++offset) = g;
427  *(++offset) = r;
428  *(++offset) = a;
429  break;
430  case SDL_PIXELFORMAT_BGRA8888:
431  *(offset) = a;
432  *(++offset) = b;
433  *(++offset) = g;
434  *(++offset) = r;
435  break;
436  default:
437  std::cout << "*** surface::put_pix: Unsupported format " << SDL_GetPixelFormatName(Info->Format) << std::endl;
438  exit(1);
439  }}
440 
442 {
443  if (!Info->Pixels) return 0;
444 
445  u_int8 r, g, b, a = SDL_ALPHA_OPAQUE;
446  u_int8 *offset = ((Uint8 *) Info->Pixels) + y * Info->Pitch + x * Info->BytesPerPixel;
447 
448  if (!alpha_channel_)
449  {
450  switch (Info->Format)
451  {
452  case SDL_PIXELFORMAT_RGB24:
453  r = *(offset);
454  g = *(++offset);
455  b = *(++offset);
456  break;
457  case SDL_PIXELFORMAT_BGR24:
458  b = *(offset);
459  g = *(++offset);
460  r = *(++offset);
461  break;
462  }
463 
464  return map_color (r, g, b, a);
465  }
466 
467  switch (Info->Format)
468  {
469  case SDL_PIXELFORMAT_BGR888:
470  r = *(++offset);
471  g = *(++offset);
472  b = *(++offset);
473  break;
474  case SDL_PIXELFORMAT_BGRA8888:
475  a = *(offset);
476  r = *(++offset);
477  g = *(++offset);
478  b = *(++offset);
479  break;
480  case SDL_PIXELFORMAT_ABGR8888:
481  r = *(offset);
482  g = *(++offset);
483  b = *(++offset);
484  a = *(++offset);
485  break;
486  case SDL_PIXELFORMAT_RGB888:
487  b = *(++offset);
488  g = *(++offset);
489  r = *(++offset);
490  break;
491  case SDL_PIXELFORMAT_ARGB8888:
492  b = *(offset);
493  g = *(++offset);
494  r = *(++offset);
495  a = *(++offset);
496  break;
497  case SDL_PIXELFORMAT_RGBA8888:
498  a = *(offset);
499  b = *(++offset);
500  g = *(++offset);
501  r = *(++offset);
502  break;
503  default:
504  std::cout << "surface::get_pix: Unsupported format " << SDL_GetPixelFormatName(Info->Format) << std::endl;
505  exit(1);
506  }
507 
508 #ifdef __BIG_ENDIAN__
509  return map_color (g, r, a, b);
510 #else
511  return map_color (r, g, b, a);
512 #endif
513 }
514 
515 void surface::set_scale(const u_int8 & new_scale)
516 {
517  // cannot scale the screen surface
518  if (this == &screen::display) return;
519 
520  // already at requested scale
521  if (scale() == new_scale)
522  return;
523 
524  if (Surface == NULL)
525  {
526  scale_ = new_scale;
527  return;
528  }
529 
530  int bpp, pitch;
531  u_int8 *target_data;
532  u_int32 rmask, gmask, bmask, amask;
533 
534  lock();
535 
536  SDL_PixelFormatEnumToMasks(Info->Format, &bpp, &rmask, &gmask, &bmask, &amask);
537  SDL_Texture *target = SDL_CreateTexture (screen::get_renderer(), Info->Format, SDL_TEXTUREACCESS_STREAMING, length()*new_scale, height()*new_scale);
538  if (!target) std::cout << "*** surface_sdl::set_scale: " << SDL_GetError() << std::endl;
539 
540 
541  SDL_LockTexture(target, NULL, (void**)&target_data, &pitch);
542  SDL_Surface *target_surf = SDL_CreateRGBSurfaceFrom(target_data, length()*new_scale, height()*new_scale, bpp, pitch, rmask, gmask, bmask, amask);
543 
544  s_int32 target_line_length = target_surf->format->BytesPerPixel * length()*new_scale;
545 
546  u_int32 real_height = height()*scale();
547  u_int32 real_length = length()*scale();
548 
549  for (s_int32 src_y = 0; src_y < real_height; src_y += scale())
550  {
551  s_int32 target_x = 0;
552  s_int32 target_x_end = 0;
553 
554  // we scale one line horizontally
555  for (s_int32 src_x = 0; src_x < real_length; src_x += scale())
556  {
557  u_int8 *src = ((Uint8 *) Info->Pixels) + src_y * Info->Pitch + src_x * Info->BytesPerPixel;
558  for (target_x_end += new_scale; target_x < target_x_end; ++target_x)
559  {
560  u_int8 *dest = target_data + target_x * Info->BytesPerPixel;
561  memcpy(dest, src, Info->BytesPerPixel);
562  }
563  }
564 
565  // the next lines will be the same, so we just copy them
566  for (u_int32 i = 1; i < new_scale; i++)
567  {
568  u_int8 *target_next_line = target_data + target_surf->pitch;
569  memcpy (target_next_line, target_data, target_line_length);
570  target_data = target_next_line;
571  }
572 
573  // goto next line
574  target_data += target_surf->pitch;
575  }
576 
577  // scaling complete, now swap the underlying texture
578  SDL_DestroyTexture(Surface);
579  Surface = target;
580  Info->Pixels = target_surf->pixels;
581  scale_ = new_scale;
582 
583  unlock();
584  SDL_FreeSurface(target_surf);
585 }
586 
588 {
589  (drawable&) (*this) = (drawable&) src;
590  alpha_channel_ = src.has_alpha_channel();
591  is_masked_ = src.is_masked();
592  alpha_ = src.alpha();
593  scale_ = src.scale();
594 
595  if (Surface) SDL_DestroyTexture(Surface);
596  if (!src.Surface)
597  {
598  Surface = NULL;
599  }
600  else
601  {
602  int l, h, pitch;
603  void *src_pixels, *dst_pixels;
604 
605  SDL_QueryTexture(src.Surface, &Info->Format, NULL, &l, &h);
606  Surface = SDL_CreateTexture (screen::get_renderer(), Info->Format, SDL_TEXTUREACCESS_STREAMING, l, h);
607  if (!Surface) std::cout << "*** surface_sdl::operator=: " << SDL_GetError() << std::endl;
608 
609  SDL_LockTexture(src.Surface, NULL, &src_pixels, &pitch);
610  SDL_LockTexture(Surface, NULL, &dst_pixels, &pitch);
611 
612  while (h-- > 0)
613  {
614  memcpy (dst_pixels, src_pixels, pitch);
615  src_pixels = (u_int8*) src_pixels + pitch;
616  dst_pixels = (u_int8*) dst_pixels + pitch;
617  }
618 
619  SDL_UnlockTexture(Surface);
620  }
621 
622  return *this;
623 }
624 
625 
626 
627 // Protected methods
628 
629 
630 
632 {
633  if (l == length () && h == height ()) return;
634 
635  if (Surface) SDL_DestroyTexture(Surface);
636 
637  set_length (l);
638  set_height (h);
639 
640  if (l == 0 || h == 0)
641  {
642  Surface = NULL;
643  return;
644  }
645 
646  // is screen surface initialized?
647  if (screen::get_renderer())
648  {
649 #ifdef __BIG_ENDIAN__
650  Info->Format = has_alpha_channel() ? SDL_PIXELFORMAT_ARGB8888 : SDL_PIXELFORMAT_RGB24;
651 #else
652  Info->Format = has_alpha_channel() ? SDL_PIXELFORMAT_ABGR8888 : SDL_PIXELFORMAT_BGR24;
653 #endif
654  Surface = SDL_CreateTexture (screen::get_renderer(), Info->Format, SDL_TEXTUREACCESS_STREAMING, l * scale(), h * scale());
655  if (!Surface) std::cout << "*** surface::resize: " << SDL_GetError() << std::endl;
656  }
657  else
658  {
659  Surface = NULL;
660  std::cout << "*** surface:resize: screen surface not initialized!" << std::endl;
661  exit(1);
662  }
663 }
664 
666 {
667  if (Surface)
668  {
669  SDL_DestroyTexture(Surface);
670  Surface = NULL;
671  set_length (0);
672  set_height (0);
673  set_alpha (255);
674  is_masked_ = false;
675  alpha_channel_ = false;
676  }
677 }
678 
679 void surface::set_data(void * data, u_int16 l, u_int16 h, u_int8 bytes_per_pixel, u_int32 red_mask,
680  u_int32 green_mask, u_int32 blue_mask, u_int32 alpha_mask)
681 {
682  if (Surface) SDL_DestroyTexture(Surface);
683 
684  scale_ = 1;
685 
686  set_length(l);
687  set_height(h);
688 
689  if (l == 0 || h == 0)
690  {
691  Surface = NULL;
692  return;
693  }
694 
695  alpha_channel_ = alpha_mask != 0;
696 
697  Info->Format = SDL_MasksToPixelFormatEnum (bytes_per_pixel * 8, red_mask, green_mask, blue_mask, alpha_mask);
698  Surface = SDL_CreateTexture (screen::get_renderer(), Info->Format, SDL_TEXTUREACCESS_STREAMING, l, h);
699  if (!Surface) std::cerr << "*** surface::set_data: " << SDL_GetError() << std::endl;
700 
701  lock(NULL);
702 
703  int pitch = bytes_per_pixel * l;
704  void *src = data;
705 
706  while (h-- > 0)
707  {
708  memcpy (Info->Pixels, src, pitch);
709  src = (u_int8*) src + pitch;
710  Info->Pixels = (u_int8*) Info->Pixels + Info->Pitch;
711  }
712 
713  unlock();
714 
715  if (mask_changed_)
716  {
717  set_mask(true);
718  }
719 }
720 
721 void * surface::get_data (u_int8 bytes_per_pixel,
722  u_int32 red_mask, u_int32 green_mask,
723  u_int32 blue_mask, u_int32 alpha_mask) const
724 {
725  if (scale() != 1)
726  {
727  // always save images without scaling
728  surface tmp;
729  tmp = *this;
730  tmp.set_scale(1);
731  return tmp.get_data(bytes_per_pixel, red_mask, green_mask, blue_mask, alpha_mask);
732  }
733 
734  lock(NULL);
735 
736  u_int32 dst_format = SDL_MasksToPixelFormatEnum(bytes_per_pixel*8, red_mask, green_mask, blue_mask, alpha_mask);
737  void *dst_pixels = calloc (length() * height(), bytes_per_pixel);
738  int dst_pitch = length() * bytes_per_pixel;
739 
740  if (dst_format != Info->Format)
741  {
742  SDL_ConvertPixels(length(), height(), Info->Format, Info->Pixels, Info->Pitch, dst_format, dst_pixels, dst_pitch);
743  }
744  else
745  {
746  u_int8 *dest = (u_int8*) dst_pixels;
747  int h = height();
748  while (h-- > 0)
749  {
750  memcpy (dest, (u_int8*) Info->Pixels, Info->Pitch);
751  Info->Pixels = (u_int8*) Info->Pixels + Info->Pitch;
752  dest = dest + dst_pitch;
753  }
754  }
755 
756  return dst_pixels;
757 }
758 
759 
760 // Private methods
761 
762 
763 
764 void surface::setup_rects (s_int16 x, s_int16 y, s_int16 sx, s_int16 sy,
765  u_int16 sl, u_int16 sh, const drawing_area * draw_to) const
766 {
767  if (draw_to)
768  {
769  drawing_area im_zone (x, y, sl, sh);
770  im_zone.assign_drawing_area (draw_to);
771 
772  SDL_Rect da_int = im_zone.setup_rects ();
773  dstrect.x = da_int.x;
774  dstrect.y = da_int.y;
775  dstrect.w = da_int.w;
776  dstrect.h = da_int.h;
777 
778  srcrect = dstrect;
779  srcrect.x = x < dstrect.x ? sx + dstrect.x - x : sx;
780  srcrect.y = y < dstrect.y ? sy + dstrect.y - y : sy;
781  }
782  else
783  {
784  srcrect.x = sx;
785  srcrect.y = sy;
786  srcrect.w = sl;
787  srcrect.h = sh;
788 
789  dstrect = srcrect;
790  dstrect.x = x;
791  dstrect.y = y;
792  }
793 }
bool has_alpha_channel() const
Returns whether the surface has an alpha channel.
Definition: surface.h:155
void set_length(u_int16 l)
Sets the length of the drawable.
Definition: drawable.h:129
#define s_int32
32 bits long signed integer
Definition: types.h:50
SDL_Texture * Surface
the surface
Definition: surface.h:440
u_int16 height() const
Returns the height of the drawable.
Definition: drawable.h:91
#define u_int16
16 bits long unsigned integer
Definition: types.h:38
void set_height(u_int16 h)
Sets the height of the drawable.
Definition: drawable.h:139
u_int32 BytesPerPixel
number of bytes used to represent the format
Definition: surface.h:65
u_int16 length() const
Returns the length of the drawable.
Definition: drawable.h:80
Class where drawables can actually be drawn to.
Definition: surface.h:85
Declares the screen class.
Definition: str_hash.h:71
void fillrect(s_int16 x, s_int16 y, u_int16 l, u_int16 h, u_int32 col, drawing_area *da_opt=NULL)
Fills an area of the surface with a given color.
Definition: surface.cc:239
u_int8 scale_
current scale
Definition: surface.h:443
u_int8 scale() const
Get the surfaces current scaling factor.
Definition: surface.h:163
#define u_int32
32 bits long unsigned integer
Definition: types.h:41
#define u_int8
8 bits long unsigned integer
Definition: types.h:35
u_int32 get_pix(u_int16 x, u_int16 y) const
Gets a pixel from the surface.
Definition: surface.cc:441
static u_int8 scale()
Scale factor of the screen.
Definition: screen.h:118
void resize(u_int16 l, u_int16 h)
Resize this surface.
Definition: surface.cc:631
static u_int16 offset_x()
X offset of the viewport.
Definition: screen.h:126
int Pitch
the pitch of the locked Surface
Definition: surface.h:61
void clear()
Resets the surface to it&#39;s initial state, that is totally empty.
Definition: surface.cc:665
Implements "drawing zones" for drawing operations.
Definition: drawing_area.h:54
static u_int16 offset_y()
Y offset of the viewport.
Definition: screen.h:134
void * Pixels
the pixel data of the locked Surface
Definition: surface.h:59
void set_alpha(u_int8 a, const bool &alpha_channel=false)
Sets the alpha value of the surface.
Definition: surface.cc:106
#define s_int16
16 bits long signed integer
Definition: types.h:47
void unlock() const
Unlock the surface after you&#39;ve worked on it&#39;s pixels with the get_pix () and put_pix () methods...
Definition: surface.cc:336
void set_scale(const u_int8 &scale)
Change the scale of the surface to the given value, resizing the internal texture appropriately...
Definition: surface.cc:515
Declares the surface class.
surface & operator=(const surface &src)
Surface copy (similar to copy ()).
Definition: surface.cc:587
s_int16 offset_x_
sub-pixel offset
Definition: surface.h:446
bool is_masked() const
Returns whether a surface is masked or not.
Definition: surface.h:118
static surface display
The actual screen surface.
Definition: screen.h:70
u_int32 Format
the format of the surface
Definition: surface.h:63
SDL_Rect setup_rects() const
Gets the real parameters of this drawing_area.
Definition: drawing_area.cc:52
Abstract class for drawable objects manipulation.
Definition: drawable.h:59
void lock() const
Locks the surface.
Definition: surface.h:271
static u_int32 trans_col()
Returns the translucent color in screen&#39;s depth format.
Definition: screen.h:110
surface(const u_int8 &scale=1)
Default constructor.
Definition: surface.cc:41
void set_mask(bool m)
Sets the mask parameter of the surface.
Definition: surface.cc:59
virtual ~surface()
Destructor.
Definition: surface.cc:53
u_int8 alpha() const
Returns the alpha value of the surface.
Definition: surface.h:136
void draw(s_int16 x, s_int16 y, const drawing_area *da_opt=NULL, surface *target=NULL) const
Draw the surface.
Definition: surface.h:191
void put_pix(u_int16 x, u_int16 y, u_int32 col)
Puts a pixel of a given color.
Definition: surface.cc:347
SDL_Surface * to_sw_surface(SDL_Rect *rect=NULL) const
Create a software surface backed by the (streaming) texture data.
Definition: surface.cc:123