-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsurface.h
212 lines (195 loc) · 7.07 KB
/
surface.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// Template, major revision 7
// IGAD/NHTV - Jacco Bikker - 2006-2015
#pragma once
namespace Tmpl8 {
#include "emmintrin.h"
#define REDMASK (0xff0000)
#define GREENMASK (0x00ff00)
#define BLUEMASK (0x0000ff)
#define REDBLUE (0x00FF00FF)
//#define ADDPLOT1
//#define ADDPLOT2
typedef unsigned long Pixel;
inline Pixel AddBlend(Pixel a_Color1, Pixel a_Color2)
{
#ifdef ADDPLOT2
__m128i mask = _mm_set_epi32(BLUEMASK, GREENMASK, REDMASK, 0);
union { int t[4]; __m128i c1; };
c1 = _mm_set_epi32(a_Color1, a_Color1, a_Color1, 0);
__m128i c2 = _mm_set_epi32(a_Color2, a_Color2, a_Color2, 0);
c1 = _mm_and_si128(c1, mask);
c2 = _mm_and_si128(c2, mask);
c1 = _mm_add_epi32(c1, c2);
c2 = _mm_and_si128(c1, mask);
t[1] = (t[1] >> 24) * REDMASK;
t[2] = (t[2] >> 16) * GREENMASK;
t[3] = (t[3] >> 8) * BLUEMASK;
c1 = _mm_or_si128(c1, c2);
return (t[1] + t[2] + t[3]);
#endif
#ifndef ADDPLOT2
const unsigned int t1 = a_Color1 & REDMASK;
const unsigned int t2 = a_Color2 & REDMASK;
const unsigned int r = t1 + t2;
const unsigned int g = (a_Color1 & GREENMASK) + (a_Color2 & GREENMASK);
const unsigned int b = (a_Color1 & BLUEMASK) + (a_Color2 & BLUEMASK);
const unsigned t3 = r & REDMASK;
const unsigned t4 = REDMASK * (r >> 24);
const unsigned r1 = t3 | t4;
const unsigned g1 = (g & GREENMASK)| (GREENMASK * (g >> 16));
const unsigned b1 = (b & BLUEMASK) | (BLUEMASK * (b >> 8));
return (r1 + g1 + b1);
#endif // !ADDPLOT
}
// subtractive blending
inline Pixel SubBlend( Pixel a_Color1, Pixel a_Color2 )
{
int red = (a_Color1 & REDMASK) - (a_Color2 & REDMASK);
int green = (a_Color1 & GREENMASK) - (a_Color2 & GREENMASK);
int blue = (a_Color1 & BLUEMASK) - (a_Color2 & BLUEMASK);
if (red < 0) red = 0;
if (green < 0) green = 0;
if (blue < 0) blue = 0;
return (Pixel)(red + green + blue);
}
inline Pixel ScaleColor( Pixel a_Color, unsigned int a_Scale )
{
unsigned int rb = (((a_Color & (REDMASK|BLUEMASK)) * a_Scale) >> 8) & (REDMASK|BLUEMASK);
unsigned int g = (((a_Color & GREENMASK) * a_Scale) >> 8) & GREENMASK;
return rb + g;
}
class Color
{
public:
Color() : b( 0.0f ), g( 0.0f ), r( 0.0f ), a( 0.0f ) {};
Color( float a_R, float a_G, float a_B ) : b( a_R ), g( a_G ), r( a_B ), a( 0.0f ) {};
void Set( float a_R, float a_G, float a_B ) { b = a_B; g = a_G; r = a_R; a = 0; }
void operator += ( const Color& a_V ) { b += a_V.b; g += a_V.g; r += a_V.r; }
void operator += ( Color* a_V ) { b += a_V->b; g += a_V->g; r += a_V->r; }
void operator -= ( const Color& a_V ) { b -= a_V.b; g -= a_V.g; r -= a_V.r; }
void operator -= ( Color* a_V ) { b -= a_V->b; g -= a_V->g; r -= a_V->r; }
void operator *= ( const float f ) { b *= f; g *= f; r *= f; }
void operator *= ( const Color& a_V ) { b *= a_V.b; g *= a_V.g; r *= a_V.r; }
void operator *= ( Color* a_V ) { b *= a_V->b; g *= a_V->g; r *= a_V->r; }
Color operator- () const { return Color( -r, -g, -b ); }
friend Color operator + ( const Color& v1, const Color& v2 ) { return Color( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b ); }
friend Color operator - ( const Color& v1, const Color& v2 ) { return Color( v1.r - v2.r, v1.g - v2.g, v1.b - v2.b ); }
friend Color operator + ( const Color& v1, Color* v2 ) { return Color( v1.r + v2->r, v1.g + v2->g, v1.b + v2->b ); }
friend Color operator - ( const Color& v1, Color* v2 ) { return Color( v1.r - v2->r, v1.g - v2->g, v1.b - v2->b ); }
friend Color operator * ( const Color& v, const float f ) { return Color( v.r * f, v.g * f, v.b * f ); }
friend Color operator * ( const Color& v1, const Color& v2 ) { return Color( v1.r * v2.r, v1.g * v2.g, v1.b * v2.b ); }
friend Color operator * ( const float f, const Color& v ) { return Color( v.r * f, v.g * f, v.b * f ); }
friend Color operator / ( const Color& v, const float f ) { float r = 1.0f / f; return Color( v.r * r, v.g * r, v.b * r ); }
union
{
struct { float b, g, r, a; };
float cell[4];
__m128 rgba;
__m128i irgba;
};
};
class Surface
{
enum
{
OWNER = 1
};
public:
// constructor / destructor
Surface( int a_Width, int a_Height, Pixel* a_Buffer, int a_Pitch );
Surface( int a_Width, int a_Height );
Surface( char* a_File );
~Surface();
// member data access
Pixel* GetBuffer() { return m_Buffer; }
void SetBuffer( Pixel* a_Buffer ) { m_Buffer = a_Buffer; }
int GetWidth() { return m_Width; }
int GetHeight() { return m_Height; }
int GetPitch() { return m_Pitch; }
void SetPitch( int a_Pitch ) { m_Pitch = a_Pitch; }
void ParseHeader( unsigned char* a_Header );
// Special operations
void InitCharset();
void SetChar( int c, char* c1, char* c2, char* c3, char* c4, char* c5 );
void Centre( char* a_String, int y1, Pixel color );
void Print( char* a_String, int x1, int y1, Pixel color );
void Clear( Pixel a_Color );
void Line( float x1, float y1, float x2, float y2, Pixel color );
void AddLine( float x1, float y1, float x2, float y2, Pixel c );
void ThickLine( int ax1, int ay1, int ax2, int ay2, Pixel c );
void Plot( int x, int y, Pixel c );
void AddPlot( int x, int y, Pixel c );
void LoadImage( char* a_File );
void CopyTo( Surface* a_Dst, int a_X, int a_Y );
void BlendCopyTo( Surface* a_Dst, int a_X, int a_Y );
void ScaleColor( unsigned int a_Scale );
void Box( int x1, int y1, int x2, int y2, Pixel color );
void Bar( int x1, int y1, int x2, int y2, Pixel color );
void Resize( Surface* a_Orig );
private:
// Attributes
Pixel* m_Buffer;
int m_Width, m_Height, m_Pitch;
// Static attributes for the buildin font
char s_Font[51][5][5];
int s_Transl[256];
};
class Sprite
{
public:
// Sprite flags
enum
{
FLARE = (1<< 0),
OPFLARE = (1<< 1),
FLASH = (1<< 4),
DISABLED = (1<< 6),
GMUL = (1<< 7),
BLACKFLARE = (1<< 8),
BRIGHTEST = (1<< 9),
RFLARE = (1<<12),
GFLARE = (1<<13),
NOCLIP = (1<<14)
};
// Structors
Sprite( Surface* a_Surface, unsigned int a_NumFrames );
Sprite( Surface* a_Surface, unsigned int a_NumFrames, unsigned int a_Flags );
~Sprite();
// Methods
void Draw( int a_X, int a_Y, Surface* a_Target = 0 );
void DrawScaled( int a_X, int a_Y, int a_Width, int a_Height, Surface* a_Target );
void SetFlags( unsigned int a_Flags ) { m_Flags = a_Flags; }
void SetFrame( unsigned int a_Index ) { m_CurrentFrame = a_Index; }
unsigned int GetFlags() const { return m_Flags; }
int GetWidth() { return m_Width; }
int GetHeight() { return m_Height; }
Pixel* GetBuffer() { return m_Surface->GetBuffer(); }
unsigned int Frames() { return m_NumFrames; }
Surface* GetSurface() { return m_Surface; }
private:
// Methods
void InitializeStartData();
// Attributes
int m_Width, m_Height, m_Pitch;
unsigned int m_NumFrames;
unsigned int m_CurrentFrame;
unsigned int m_Flags;
unsigned int** m_Start;
Surface* m_Surface;
};
class Font
{
public:
Font();
Font( char* a_File, char* a_Chars );
~Font();
void Print( Surface* a_Target, char* a_Text, int a_X, int a_Y, bool clip = false );
void Centre( Surface* a_Target, char* a_Text, int a_Y );
int Width( char* a_Text );
int Height() { return m_Surface->GetHeight(); }
void YClip( int y1, int y2 ) { m_CY1 = y1; m_CY2 = y2; }
private:
Surface* m_Surface;
int* m_Offset, *m_Width, *m_Trans, m_Height, m_CY1, m_CY2;
};
}; // namespace Tmpl8