-
Notifications
You must be signed in to change notification settings - Fork 59
/
Color.h
134 lines (107 loc) · 4.68 KB
/
Color.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
OpenLieroX
color type and related functions
code under LGPL
created 10-01-2007
*/
#ifndef __COLOR_H__
#define __COLOR_H__
#include <SDL.h>
#include <cassert>
#include "MathLib.h"
#include "CodeAttributes.h"
///////////////////
// If you want to use the adress of some Uint32 directly with memcpy or similar, use this
INLINE Uint32 SDLColourToNativeColour(Uint32 pixel, short bpp) {
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
return (pixel << (32 - 8 * bpp));
#else
return pixel;
#endif
}
/////////////////
// If you copied some data directly with memcpy into an Uint32, use this
INLINE Uint32 NativeColourToSDLColour(Uint32 pixel, short bpp) {
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
return (pixel >> (32 - 8 * bpp));
#else
return pixel;
#endif
}
///////////////
// Get the specified component from the pixel (grabbed from SDL)
INLINE Uint8 GetR(Uint32 pixel, SDL_PixelFormat *fmt) {
return (Uint8)((((pixel & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss) +
(((pixel & fmt->Rmask) >> fmt->Rshift) >> (8 - (fmt->Rloss << 1))));
}
INLINE Uint8 GetG(Uint32 pixel, SDL_PixelFormat *fmt) {
return (Uint8)((((pixel & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss) +
(((pixel & fmt->Gmask) >> fmt->Gshift) >> (8 - (fmt->Gloss << 1))));
}
INLINE Uint8 GetB(Uint32 pixel, SDL_PixelFormat *fmt) {
return (Uint8)((((pixel & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss) +
(((pixel & fmt->Bmask) >> fmt->Bshift) >> (8 - (fmt->Bloss << 1))));
}
INLINE Uint8 GetA(Uint32 pixel, SDL_PixelFormat *fmt) {
return (Uint8)((((pixel & fmt->Amask) >> fmt->Ashift) << fmt->Aloss) +
(((pixel & fmt->Amask) >> fmt->Ashift) >> (8 - (fmt->Aloss << 1))));
}
extern SDL_PixelFormat mainPixelFormat;
INLINE SDL_PixelFormat* getMainPixelFormat() {
return &mainPixelFormat;
}
///////////////
// Returns true if the two colors are the same, ignoring the alpha
// HINT: both colors have to be in the same pixelformat
INLINE bool EqualRGB(Uint32 p1, Uint32 p2, const SDL_PixelFormat* fmt) {
return ((p1&(fmt->Rmask|fmt->Gmask|fmt->Bmask)) == (p2&(fmt->Rmask|fmt->Gmask|fmt->Bmask)));
}
///////////////
// Creates a int colour based on the 3 components
// HINT: format is that one from videosurface!
INLINE Uint32 MakeColour(Uint8 r, Uint8 g, Uint8 b) {
return SDL_MapRGB(getMainPixelFormat(), r, g, b);
}
///////////////
// Creates a int colour based on the 4 components
// HINT: format is that one from videosurface!
INLINE Uint32 MakeColour(Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
return SDL_MapRGBA(getMainPixelFormat(), r, g, b, a);
}
// Device-independent color
struct Color {
INLINE Color() : r(0), g(0), b(0), a(SDL_ALPHA_OPAQUE) {}
INLINE Color(Uint8 _r, Uint8 _g, Uint8 _b) : r(_r), g(_g), b(_b), a(SDL_ALPHA_OPAQUE) {}
INLINE Color(Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a) : r(_r), g(_g), b(_b), a(_a) {}
INLINE Color(const SDL_PixelFormat *f, Uint32 cl) { SDL_GetRGBA(cl, f, &r, &g, &b, &a); }
INLINE Color(const SDL_Color& cl) : r(cl.r), g(cl.g), b(cl.b), a(SDL_ALPHA_OPAQUE) {}
static Color fromDefault(Uint32 cl) { return Color(Uint8(cl >> 24), Uint8(cl >> 16), Uint8(cl >> 8), Uint8(cl)); }
static Color fromMainFormat(Uint32 i) { return Color(getMainPixelFormat(), i); }
Uint8 r;
Uint8 g;
Uint8 b;
Uint8 a;
INLINE Uint32 get(const SDL_PixelFormat *f) const { return SDL_MapRGBA(f, r, g, b, a); }
Uint32 getDefault() const { return (Uint32(r) << 24) | (Uint32(g) << 16) | (Uint32(b) << 8) | Uint32(a); }
Color derived(Sint16 _r, Sint16 _g, Sint16 _b, Sint16 _a) const {
return Color(
Uint8(CLAMP(_r + r, 0, 255)),
Uint8(CLAMP(_g + g, 0, 255)),
Uint8(CLAMP(_b + b, 0, 255)),
Uint8(CLAMP(_a + a, 0, 255)));
}
void set(const SDL_PixelFormat *f, Uint32 cl) { SDL_GetRGBA(cl, f, &r, &g, &b, &a); }
INLINE bool operator == ( const Color & c ) const { return r == c.r && g == c.g && b == c.b && a == c.a; };
INLINE bool operator != ( const Color & c ) const { return ! ( *this == c ); };
Color operator * ( float f ) const { return Color( Uint8(CLAMP(r*f,0.0f,255.0f)), Uint8(CLAMP(g*f,0.0f,255.0f)), Uint8(CLAMP(b*f,0.0f,255.0f)), a ); };
Color operator + ( const Color & c ) const { return Color( (Uint8)CLAMP(Uint16(r)+c.r,0,255), (Uint8)CLAMP(Uint16(g)+c.g,0,255), (Uint8)CLAMP(Uint16(b)+c.b,0,255), (Uint8)CLAMP(Uint16(a)+c.a,0,255)); };
bool operator<(const Color& c) const {
if(r != c.r) return r < c.r;
if(g != c.g) return g < c.g;
if(b != c.b) return b < c.b;
return a < c.a;
}
Uint8& operator[](int i) { switch(i) { case 0: return r; case 1: return g; case 2: return b; case 3: return a; default: assert(false); } return *((Uint8*)NULL); }
Uint8 operator[](int i) const { switch(i) { case 0: return r; case 1: return g; case 2: return b; case 3: return a; default: assert(false); } return 0; }
};
#endif