OpenXcom  1.0
Open-source clone of the original X-Com
ShaderDrawHelper.h
1 #pragma once
2 /*
3  * Copyright 2010-2016 OpenXcom Developers.
4  *
5  * This file is part of OpenXcom.
6  *
7  * OpenXcom is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * OpenXcom is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with OpenXcom. If not, see <http://www.gnu.org/licenses/>.
19  */
20 #include "Surface.h"
21 #include "GraphSubset.h"
22 #include <vector>
23 
24 namespace OpenXcom
25 {
26 namespace helper
27 {
28 
33 class Nothing
34 {
35 
36 };
37 
42 template<typename T>
43 class Scalar
44 {
45 public:
46  T& ref;
47  inline Scalar(T& t) : ref(t)
48  {
49 
50  }
51 };
52 
53 
59 template<typename Pixel>
61 {
62 public:
63  typedef Pixel* PixelPtr;
64  typedef Pixel& PixelRef;
65 
66 protected:
67  const PixelPtr _orgin;
68  const GraphSubset _range_base;
69  GraphSubset _range_domain;
70  const int _pitch;
71 
72 public:
74  inline ShaderBase(const ShaderBase& s):
75  _orgin(s.ptr()),
76  _range_base(s._range_base),
77  _range_domain(s.getDomain()),
78  _pitch(s.pitch())
79  {
80 
81  }
82 
93  inline ShaderBase(std::vector<Pixel>& f, int max_x, int max_y):
94  _orgin(&(f[0])),
95  _range_base(max_x, max_y),
96  _range_domain(max_x, max_y),
97  _pitch(max_x)
98  {
99 
100  }
101 
102  inline PixelPtr ptr() const
103  {
104  return _orgin;
105  }
106  inline int pitch() const
107  {
108  return _pitch;
109  }
110 
111  inline void setDomain(const GraphSubset& g)
112  {
113  _range_domain = GraphSubset::intersection(g, _range_base);
114  }
115  inline const GraphSubset& getDomain() const
116  {
117  return _range_domain;
118  }
119  inline const GraphSubset& getBaseDomain() const
120  {
121  return _range_base;
122  }
123 
124  inline const GraphSubset& getImage() const
125  {
126  return _range_domain;
127  }
128 };
129 
135 template<typename Pixel>
136 class ShaderBase<const Pixel>
137 {
138 public:
139  typedef const Pixel* PixelPtr;
140  typedef const Pixel& PixelRef;
141 
142 protected:
143  const PixelPtr _orgin;
144  const GraphSubset _range_base;
145  GraphSubset _range_domain;
146  const int _pitch;
147 
148 public:
150  inline ShaderBase(const ShaderBase& s):
151  _orgin(s.ptr()),
152  _range_base(s.getBaseDomain()),
153  _range_domain(s.getDomain()),
154  _pitch(s.pitch())
155  {
156 
157  }
158 
160  inline ShaderBase(const ShaderBase<Pixel>& s):
161  _orgin(s.ptr()),
162  _range_base(s.getBaseDomain()),
163  _range_domain(s.getDomain()),
164  _pitch(s.pitch())
165  {
166 
167  }
168 
179  inline ShaderBase(const std::vector<Pixel>& f, int max_x, int max_y):
180  _orgin(&(f[0])),
181  _range_base(max_x, max_y),
182  _range_domain(max_x, max_y),
183  _pitch(max_x)
184  {
185 
186  }
187 
188  inline PixelPtr ptr() const
189  {
190  return _orgin;
191  }
192  inline int pitch() const
193  {
194  return _pitch;
195  }
196 
197  inline void setDomain(const GraphSubset& g)
198  {
199  _range_domain = GraphSubset::intersection(g, _range_base);
200  }
201  inline const GraphSubset& getDomain() const
202  {
203  return _range_domain;
204  }
205  inline const GraphSubset& getBaseDomain() const
206  {
207  return _range_base;
208  }
209 
210  inline const GraphSubset& getImage() const
211  {
212  return _range_domain;
213  }
214 };
215 
222 template<>
223 class ShaderBase<Uint8>
224 {
225 public:
226  typedef Uint8* PixelPtr;
227  typedef Uint8& PixelRef;
228 
229 protected:
230  const PixelPtr _orgin;
231  const GraphSubset _range_base;
232  GraphSubset _range_domain;
233  const int _pitch;
234 
235 public:
237  inline ShaderBase(const ShaderBase& s):
238  _orgin(s.ptr()),
239  _range_base(s.getBaseDomain()),
240  _range_domain(s.getDomain()),
241  _pitch(s.pitch())
242  {
243 
244  }
245 
253  inline ShaderBase(Surface* s):
254  _orgin((Uint8*) s->getSurface()->pixels),
255  _range_base(s->getWidth(), s->getHeight()),
256  _range_domain(s->getWidth(), s->getHeight()),
257  _pitch(s->getSurface()->pitch)
258  {
259 
260  }
261 
272  inline ShaderBase(std::vector<Uint8>& f, int max_x, int max_y):
273  _orgin(&(f[0])),
274  _range_base(max_x, max_y),
275  _range_domain(max_x, max_y),
276  _pitch(max_x)
277  {
278 
279  }
280 
281  inline PixelPtr ptr() const
282  {
283  return _orgin;
284  }
285  inline int pitch() const
286  {
287  return _pitch;
288  }
289 
290  inline void setDomain(const GraphSubset& g)
291  {
292  _range_domain = GraphSubset::intersection(g, _range_base);
293  }
294  inline const GraphSubset& getDomain() const
295  {
296  return _range_domain;
297  }
298  inline const GraphSubset& getBaseDomain() const
299  {
300  return _range_base;
301  }
302 
303  inline const GraphSubset& getImage() const
304  {
305  return _range_domain;
306  }
307 };
308 
315 template<>
316 class ShaderBase<const Uint8>
317 {
318 public:
319  typedef const Uint8* PixelPtr;
320  typedef const Uint8& PixelRef;
321 
322 protected:
323  const PixelPtr _orgin;
324  const GraphSubset _range_base;
325  GraphSubset _range_domain;
326  const int _pitch;
327 
328 public:
330  inline ShaderBase(const ShaderBase& s):
331  _orgin(s.ptr()),
332  _range_base(s.getBaseDomain()),
333  _range_domain(s.getDomain()),
334  _pitch(s.pitch())
335  {
336 
337  }
338 
340  inline ShaderBase(const ShaderBase<Uint8>& s):
341  _orgin(s.ptr()),
342  _range_base(s.getBaseDomain()),
343  _range_domain(s.getDomain()),
344  _pitch(s.pitch())
345  {
346 
347  }
348 
356  inline ShaderBase(const Surface* s):
357  _orgin((Uint8*) s->getSurface()->pixels),
358  _range_base(s->getWidth(), s->getHeight()),
359  _range_domain(s->getWidth(), s->getHeight()),
360  _pitch(s->getSurface()->pitch)
361  {
362 
363  }
364 
375  inline ShaderBase(const std::vector<Uint8>& f, int max_x, int max_y):
376  _orgin(&(f[0])),
377  _range_base(max_x, max_y),
378  _range_domain(max_x, max_y),
379  _pitch(max_x)
380  {
381 
382  }
383 
384  inline PixelPtr ptr() const
385  {
386  return _orgin;
387  }
388  inline int pitch() const
389  {
390  return _pitch;
391  }
392 
393  inline void setDomain(const GraphSubset& g)
394  {
395  _range_domain = GraphSubset::intersection(g, _range_base);
396  }
397  inline const GraphSubset& getDomain() const
398  {
399  return _range_domain;
400  }
401  inline const GraphSubset& getBaseDomain() const
402  {
403  return _range_base;
404  }
405 
406  inline const GraphSubset& getImage() const
407  {
408  return _range_domain;
409  }
410 };
411 
412 
415 template<typename SurfaceType>
416 struct controler
417 {
418  //NOT IMPLEMENTED ANYWHERE!
419  //you need create your own specification or use different type, no default version
420 
426  inline const GraphSubset& get_range();
432  inline void mod_range(GraphSubset& g);
437  inline void set_range(const GraphSubset& g);
438 
439  inline void mod_y(int& begin, int& end);
440  inline void set_y(const int& begin, const int& end);
441  inline void inc_y();
442 
443 
444  inline void mod_x(int& begin, int& end);
445  inline void set_x(const int& begin, const int& end);
446  inline void inc_x();
447 
448  inline int& get_ref();
449 };
450 
452 template<typename T>
453 struct controler<Scalar<T> >
454 {
455  T& ref;
456 
457  inline controler(const Scalar<T>& s) : ref(s.ref)
458  {
459 
460  }
461 
462  //cant use this function
463  //inline GraphSubset get_range()
464 
465  inline void mod_range(GraphSubset&)
466  {
467  //nothing
468  }
469  inline void set_range(const GraphSubset&)
470  {
471  //nothing
472  }
473 
474  inline void mod_y(int&, int&)
475  {
476  //nothing
477  }
478  inline void set_y(const int&, const int&)
479  {
480  //nothing
481  }
482  inline void inc_y()
483  {
484  //nothing
485  }
486 
487 
488  inline void mod_x(int&, int&)
489  {
490  //nothing
491  }
492  inline void set_x(const int&, const int&)
493  {
494  //nothing
495  }
496  inline void inc_x()
497  {
498  //nothing
499  }
500 
501  inline T& get_ref()
502  {
503  return ref;
504  }
505 };
506 
508 template<>
510 {
511  const int i;
512  inline controler(const Nothing&) : i(0)
513  {
514 
515  }
516 
517  //cant use this function
518  //inline GraphSubset get_range()
519 
520  inline void mod_range(GraphSubset&)
521  {
522  //nothing
523  }
524  inline void set_range(const GraphSubset&)
525  {
526  //nothing
527  }
528 
529  inline void mod_y(int&, int&)
530  {
531  //nothing
532  }
533  inline void set_y(const int&, const int&)
534  {
535  //nothing
536  }
537  inline void inc_y()
538  {
539  //nothing
540  }
541 
542  inline void mod_x(int&, int&)
543  {
544  //nothing
545  }
546  inline void set_x(const int&, const int&)
547  {
548  //nothing
549  }
550  inline void inc_x()
551  {
552  //nothing
553  }
554 
555  inline const int& get_ref()
556  {
557  return i;
558  }
559 };
560 
561 template<typename PixelPtr, typename PixelRef>
563 {
564 
565  const PixelPtr data;
566  PixelPtr ptr_pos_y;
567  PixelPtr ptr_pos_x;
568  GraphSubset range;
569  int start_x;
570  int start_y;
571 
572  const std::pair<int, int> step;
573 
574 
575  controler_base(PixelPtr base, const GraphSubset& d, const GraphSubset& r, const std::pair<int, int>& s) :
576  data(base + d.beg_x*s.first + d.beg_y*s.second),
577  ptr_pos_y(0), ptr_pos_x(0),
578  range(r),
579  start_x(), start_y(),
580  step(s)
581  {
582 
583  }
584 
585 
586  inline const GraphSubset& get_range()
587  {
588  return range;
589  }
590 
591  inline void mod_range(GraphSubset& r)
592  {
593  r = GraphSubset::intersection(range, r);
594  }
595 
596  inline void set_range(const GraphSubset& r)
597  {
598  start_x = r.beg_x - range.beg_x;
599  start_y = r.beg_y - range.beg_y;
600  range = r;
601  }
602 
603  inline void mod_y(int&, int&)
604  {
605  ptr_pos_y = data + step.first * start_x + step.second * start_y;
606  }
607  inline void set_y(const int& begin, const int&)
608  {
609  ptr_pos_y += step.second*begin;
610  }
611  inline void inc_y()
612  {
613  ptr_pos_y += step.second;
614  }
615 
616 
617  inline void mod_x(int&, int&)
618  {
619  ptr_pos_x = ptr_pos_y;
620  }
621  inline void set_x(const int& begin, const int&)
622  {
623  ptr_pos_x += step.first*begin;
624  }
625  inline void inc_x()
626  {
627  ptr_pos_x += step.first;
628  }
629 
630  inline PixelRef get_ref()
631  {
632  return *ptr_pos_x;
633  }
634 };
635 
636 
637 
638 template<typename Pixel>
639 struct controler<ShaderBase<Pixel> > : public controler_base<typename ShaderBase<Pixel>::PixelPtr, typename ShaderBase<Pixel>::PixelRef>
640 {
641  typedef typename ShaderBase<Pixel>::PixelPtr PixelPtr;
642  typedef typename ShaderBase<Pixel>::PixelRef PixelRef;
643 
645 
646  controler(const ShaderBase<Pixel>& f) : base_type(f.ptr(), f.getDomain(), f.getImage(), std::make_pair(1, f.pitch()))
647  {
648 
649  }
650 
651 };
652 
653 }//namespace helper
654 
655 }//namespace OpenXcom
helper class for handling implementation differences in different surfaces types Used in function Sha...
Definition: ShaderDrawHelper.h:416
ShaderBase(const ShaderBase< Pixel > &s)
copy constructor
Definition: ShaderDrawHelper.h:160
ShaderBase(const ShaderBase &s)
copy constructor
Definition: ShaderDrawHelper.h:74
ShaderBase(Surface *s)
create surface using surface s as data source.
Definition: ShaderDrawHelper.h:253
const GraphSubset & get_range()
function used only when SurfaceType can be used as destination surface if that type should not be use...
ShaderBase(std::vector< Pixel > &f, int max_x, int max_y)
create surface using vector f as data source.
Definition: ShaderDrawHelper.h:93
ShaderBase(const std::vector< Pixel > &f, int max_x, int max_y)
create surface using vector f as data source.
Definition: ShaderDrawHelper.h:179
ShaderBase(const ShaderBase< Uint8 > &s)
copy constructor
Definition: ShaderDrawHelper.h:340
ShaderBase(const ShaderBase &s)
copy constructor
Definition: ShaderDrawHelper.h:330
This is surface argument to ShaderDraw.
Definition: ShaderDrawHelper.h:223
void set_range(const GraphSubset &g)
set final drawing range.
ShaderBase(const ShaderBase &s)
copy constructor
Definition: ShaderDrawHelper.h:237
ShaderBase(const ShaderBase &s)
copy constructor
Definition: ShaderDrawHelper.h:150
This is empty argument to ShaderDraw.
Definition: ShaderDrawHelper.h:33
Element that is blit (rendered) onto the screen.
Definition: Surface.h:38
Definition: GraphSubset.h:32
This is surface argument to ShaderDraw.
Definition: ShaderDrawHelper.h:60
This is scalar argument to ShaderDraw.
Definition: ShaderDrawHelper.h:43
ShaderBase(std::vector< Uint8 > &f, int max_x, int max_y)
create surface using vector f as data source.
Definition: ShaderDrawHelper.h:272
ShaderBase(const Surface *s)
create surface using surface s as data source.
Definition: ShaderDrawHelper.h:356
Definition: ShaderDrawHelper.h:562
void mod_range(GraphSubset &g)
function used only when SurfaceType is used as source surface.
ShaderBase(const std::vector< Uint8 > &f, int max_x, int max_y)
create surface using vector f as data source.
Definition: ShaderDrawHelper.h:375
Definition: BaseInfoState.cpp:40