Skip to content

Commit 511839d

Browse files
committed
PlayerSetup: add flags custom logos
1 parent 59482d1 commit 511839d

File tree

2 files changed

+177
-47
lines changed

2 files changed

+177
-47
lines changed

BMPUtils.h

+46-12
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ of the License, or (at your option) any later version.
99
1010
This program is distributed in the hope that it will be useful,
1111
but WITHOUT ANY WARRANTY; without even the implied warranty of
12-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1313
1414
See the GNU General Public License for more details.
1515
@@ -72,7 +72,7 @@ class CBMP
7272
bhdr.bitmapDataOffset = sizeof( bmp_t ) + cbPalBytes;
7373
bhdr.bitmapDataSize = bhdr.width * bhdr.height * pixel_size;
7474
bhdr.fileSize = bhdr.bitmapDataOffset + bhdr.bitmapDataSize;
75-
75+
7676
// constant
7777
bhdr.reserved0 = 0;
7878
bhdr.planes = 1;
@@ -81,7 +81,7 @@ class CBMP
8181
bhdr.hRes = bhdr.vRes = 0;
8282
bhdr.colors = ( pixel_size == 1 ) ? 256 : 0;
8383
bhdr.importantColors = 0;
84-
84+
8585
fileAllocated = false;
8686
data = new byte[bhdr.fileSize];
8787
memcpy( data, &bhdr, sizeof( bhdr ));
@@ -101,7 +101,7 @@ class CBMP
101101
hdr->bitmapDataSize = img_sz;
102102
hdr->fileSize = hdr->bitmapDataOffset + hdr->bitmapDataSize;
103103
}
104-
104+
105105
~CBMP()
106106
{
107107
if( data )
@@ -134,7 +134,7 @@ class CBMP
134134
byte *newData = new byte[bhdr.fileSize];
135135
memcpy( newData, &bhdr, sizeof( bhdr ));
136136
memset( newData + bhdr.bitmapDataOffset, 0, bhdr.bitmapDataSize );
137-
137+
138138
// now copy texture
139139
byte *src = GetTextureData();
140140
byte *dst = newData + bhdr.bitmapDataOffset;
@@ -152,7 +152,7 @@ class CBMP
152152
data = newData;
153153
}
154154

155-
void RemapLogo( int r, int g, int b )
155+
void RemapLogo( int stripes, const byte *rgb )
156156
{
157157
// palette is always right after header
158158
rgbquad_t *palette = GetPaletteData();
@@ -161,13 +161,47 @@ class CBMP
161161
if( GetBitmapHdr()->bitsPerPixel > 8 )
162162
return;
163163

164-
for( int i = 0; i < 256; i++ )
164+
int max_palette_slots = (int)(256 / (float)stripes) * stripes;
165+
166+
for( int i = 0; i < max_palette_slots; i += stripes )
167+
{
168+
double t = (double)i / max_palette_slots;
169+
170+
t = Q_min( t, 1.0 );
171+
172+
for( int j = 0; j < stripes; j++ )
173+
{
174+
int x = i + j;
175+
176+
palette[x].r = (byte)(rgb[j * 3 + 0] * t);
177+
palette[x].g = (byte)(rgb[j * 3 + 1] * t);
178+
palette[x].b = (byte)(rgb[j * 3 + 2] * t);
179+
}
180+
}
181+
182+
if( stripes == 1 )
183+
return;
184+
185+
const bmp_t *hdr = GetBitmapHdr();
186+
double lines_per_stripe = hdr->height / (double)stripes;
187+
byte *data = GetTextureData();
188+
189+
for( int i = 0; i < hdr->height; i++ )
165190
{
166-
float t = (float)i/256.0f;
167-
168-
palette[i].r = (byte)(r * t);
169-
palette[i].g = (byte)(g * t);
170-
palette[i].b = (byte)(b * t);
191+
int stripe = (int)(( hdr->height - i - 1 ) / lines_per_stripe );
192+
193+
for( int j = 0; j < hdr->width; j++ )
194+
{
195+
byte c = data[i * hdr->width + j];
196+
if( c == 0 )
197+
continue;
198+
199+
// remap to the palette
200+
int idx = ( c / 256.0f ) * max_palette_slots; // remap to limited palette
201+
idx = (int)((double)( idx ) / stripes) * stripes; // now remap per palette
202+
idx += stripe; // add stripe index
203+
data[i * hdr->width + j] = Q_min( idx, max_palette_slots ); //
204+
}
171205
}
172206
}
173207

menus/PlayerSetup.cpp

+131-35
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
88
99
This program is distributed in the hope that it will be useful,
1010
but WITHOUT ANY WARRANTY; without even the implied warranty of
11-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1212
1313
See the GNU General Public License for more details.
1414
@@ -34,22 +34,97 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3434

3535
#define MAX_PLAYERMODELS 100
3636

37-
static struct
37+
static const byte Orange[] = { 255, 120, 24 };
38+
static const byte Yellow[] = { 225, 180, 24 };
39+
static const byte Blue[] = { 0, 60, 255 };
40+
static const byte Ltblue[] = { 0, 167, 255 };
41+
static const byte Green[] = { 0, 167, 0 };
42+
static const byte Red[] = { 255, 43, 0 };
43+
static const byte Brown[] = { 123, 73, 0 };
44+
static const byte Ltgray[] = { 100, 100, 100 };
45+
static const byte Dkgray[] = { 36, 36, 36 };
46+
static const byte Rainbow[] = {
47+
0xE4, 0x03, 0x03,
48+
0xFF, 0x8C, 0x00,
49+
0xFF, 0xED, 0x00,
50+
0x00, 0x80, 0x26,
51+
0x24, 0x40, 0x8E,
52+
0x73, 0x29, 0x82,
53+
};
54+
static const byte Lesbian[] = {
55+
0xD5, 0x2D, 0x00,
56+
0xEF, 0x76, 0x27,
57+
0xFF, 0x9A, 0x56,
58+
0xFF, 0xFF, 0xFF,
59+
0xD1, 0x62, 0xA4,
60+
0xB5, 0x56, 0x90,
61+
0xA3, 0x02, 0x62,
62+
};
63+
static const byte Gay[] = {
64+
0x07, 0x8D, 0x70,
65+
0x26, 0xCE, 0xAA,
66+
0x98, 0xE8, 0xC1,
67+
0xFF, 0xFF, 0xFF,
68+
0x7B, 0xAD, 0xE2,
69+
0x50, 0x49, 0xCC,
70+
0x3D, 0x1A, 0x78,
71+
};
72+
static const byte Bi[] = {
73+
0xD6, 0x02, 0x70,
74+
0xD6, 0x02, 0x70,
75+
0x9B, 0x4F, 0x96,
76+
0x00, 0x38, 0xA8,
77+
0x00, 0x38, 0xA8,
78+
};
79+
static const byte Trans[] = {
80+
0x5B, 0xCE, 0xFA,
81+
0xF5, 0xA9, 0xB8,
82+
0xFF, 0xFF, 0xFF,
83+
0xF5, 0xA9, 0xB8,
84+
0x5B, 0xCE, 0xFA,
85+
};
86+
static const byte Pan[] = {
87+
0xFF, 0x21, 0x8C,
88+
0xFF, 0xD8, 0x00,
89+
0x21, 0xB1, 0xFF,
90+
};
91+
static const byte Enby[] = {
92+
0xFC, 0xF4, 0x34,
93+
0xFF, 0xFF, 0xFF,
94+
0x9C, 0x59, 0xD1,
95+
0x2C, 0x2C, 0x2C,
96+
};
97+
98+
#define FLAG_L( str, x ) str, x, sizeof( x ) / 3
99+
#define FLAG( x ) FLAG_L( #x, x )
100+
101+
// TODO: Get rid of this hardcoded mess
102+
// allow user to set whatever they want
103+
// through UI or some config lst file
104+
static const struct logo_color_t
38105
{
39106
const char *name;
40-
int r, g, b;
107+
const byte *rgb;
108+
int stripes;
41109
} g_LogoColors[] =
42110
{
43-
{ "FullColor", -1, -1, -1 },
44-
{ "#Valve_Orange", 255, 120, 24 }, // L( "Valve_Orange" )
45-
{ "#Valve_Yellow", 225, 180, 24 }, // L( "Valve_Yellow" )
46-
{ "#Valve_Blue", 0, 60, 255 }, // L( "Valve_Blue" )
47-
{ "#Valve_Ltblue", 0, 167, 255 }, // L( "Valve_Ltblue" )
48-
{ "#Valve_Green", 0, 167, 0 }, // L( "Valve_Green" )
49-
{ "#Valve_Red", 255, 43, 0 }, // L( "Valve_Red" )
50-
{ "#Valve_Brown", 123, 73, 0 }, // L( "Valve_Brown" )
51-
{ "#Valve_Ltgray", 100, 100, 100 }, // L( "Valve_Ltgray" )
52-
{ "#Valve_Dkgray", 36, 36, 36 }, // L( "Valve_Dkgray" )
111+
{ "FullColor", 0, 0 },
112+
{ FLAG_L( "#Valve_Orange", Orange ) }, // L( "Valve_Orange" )
113+
{ FLAG_L( "#Valve_Yellow", Yellow ) }, // L( "Valve_Yellow" )
114+
{ FLAG_L( "#Valve_Blue", Blue ) }, // L( "Valve_Blue" )
115+
{ FLAG_L( "#Valve_Ltblue", Ltblue ) }, // L( "Valve_Ltblue" )
116+
{ FLAG_L( "#Valve_Green", Green ) }, // L( "Valve_Green" )
117+
{ FLAG_L( "#Valve_Red", Red ) }, // L( "Valve_Red" )
118+
{ FLAG_L( "#Valve_Brown", Brown ) }, // L( "Valve_Brown" )
119+
{ FLAG_L( "#Valve_Ltgray", Ltgray ) }, // L( "Valve_Ltgray" )
120+
{ FLAG_L( "#Valve_Dkgray", Dkgray ) }, // L( "Valve_Dkgray" )
121+
{ FLAG( Rainbow ) },
122+
{ FLAG( Lesbian ) },
123+
{ FLAG( Gay ) },
124+
{ FLAG( Bi ) },
125+
{ FLAG( Trans ) },
126+
{ FLAG( Pan ) },
127+
{ FLAG( Enby ) },
53128
};
54129

55130
class CMenuPlayerSetup : public CMenuFramework
@@ -116,7 +191,7 @@ class CMenuPlayerSetup : public CMenuFramework
116191
{
117192
public:
118193
virtual void Draw();
119-
int r, g, b;
194+
const logo_color_t *color;
120195
HIMAGE hImage;
121196
} logoImage;
122197

@@ -137,14 +212,40 @@ void CMenuPlayerSetup::CMenuLogoPreview::Draw()
137212

138213
UI_DrawString( font, m_scPos, m_scSize, L( "No logo" ), colorBase, m_scChSize, QM_CENTER, ETF_SHADOW );
139214
}
140-
else
215+
else if( color->stripes == 0 )
141216
{
142-
if( r != -1 && g != -1 && b != -1 )
143-
EngFuncs::PIC_Set( hImage, r, g, b );
144-
else
145-
EngFuncs::PIC_Set( hImage, 255, 255, 255 );
217+
EngFuncs::PIC_Set( hImage, 255, 255, 255 );
146218
EngFuncs::PIC_DrawTrans( m_scPos, m_scSize );
147219
}
220+
else
221+
{
222+
const Size img_sz = EngFuncs::PIC_Size( hImage );
223+
Size ui_sz = m_scSize;
224+
wrect_t rc = { 0 };
225+
226+
rc.right = img_sz.w;
227+
rc.bottom = img_sz.h;
228+
229+
double texture_pixels_per_stripe = img_sz.h / (double)color->stripes;
230+
double screen_pixels_per_stripe = ui_sz.h / (double)color->stripes;
231+
232+
ui_sz.h = round( screen_pixels_per_stripe );
233+
234+
for( int i = 0; i < color->stripes; i++ )
235+
{
236+
wrect_t rc2 = rc;
237+
Point ui_pt;
238+
239+
rc2.top = round( i * texture_pixels_per_stripe );
240+
rc2.bottom = round(( i + 1 ) * texture_pixels_per_stripe );
241+
242+
ui_pt.x = m_scPos.x;
243+
ui_pt.y = m_scPos.y + round( i * screen_pixels_per_stripe );
244+
245+
EngFuncs::PIC_Set( hImage, color->rgb[i * 3 + 0], color->rgb[i * 3 + 1], color->rgb[i * 3 + 2] );
246+
EngFuncs::PIC_DrawTrans( ui_pt, ui_sz, &rc2 );
247+
}
248+
}
148249

149250
// draw the rectangle
150251
if( eFocusAnimation == QM_HIGHLIGHTIFFOCUS && IsCurrentSelected() )
@@ -164,7 +265,7 @@ void CMenuPlayerSetup::CModelListModel::Update( void )
164265
char name[256];
165266
char **filenames;
166267
int numFiles, i;
167-
268+
168269
m_iCount = 0;
169270

170271
// Get file list
@@ -183,12 +284,12 @@ void CMenuPlayerSetup::CModelListModel::Update( void )
183284
{
184285
COM_FileBase( filenames[i], name );
185286
Q_strncpy( models[m_iCount], name, sizeof( models[0] ) );
186-
287+
187288
// check if the path is a valid model
188289
snprintf( name, sizeof( name ), "models/player/%s/%s.mdl", models[m_iCount], models[m_iCount] );
189290
if( !EngFuncs::FileExists( name ) )
190291
continue;
191-
292+
192293
m_iCount++;
193294
}
194295
}
@@ -219,10 +320,9 @@ void CMenuPlayerSetup::CLogosListModel::Update( )
219320
{
220321
CUtlString logoFileName = filenames[i];
221322
char temp[256];
222-
bool png;
323+
bool png = logoFileName.BEndsWithCaseless( ".png" );
223324

224-
if(( png = logoFileName.BEndsWithCaseless( ".png" )) ||
225-
logoFileName.BEndsWithCaseless( ".bmp" ))
325+
if( png || logoFileName.BEndsWithCaseless( ".bmp" ))
226326
{
227327
COM_FileBase( logoFileName.String(), temp );
228328

@@ -301,7 +401,7 @@ void CMenuPlayerSetup::UpdateLogo()
301401
logoImage.hImage = EngFuncs::PIC_Load( filename, 0 );
302402
if( logosModel.IsPng( pos ))
303403
{
304-
logoImage.r = logoImage.g = logoImage.b = -1;
404+
logoImage.color = &g_LogoColors[0];
305405
logoColor.SetGrayed( true );
306406
}
307407
else
@@ -314,7 +414,7 @@ void CMenuPlayerSetup::UpdateLogo()
314414
}
315415
else
316416
{
317-
logoImage.r = logoImage.g = logoImage.b = -1;
417+
logoImage.color = &g_LogoColors[0];
318418
logoColor.SetGrayed( true );
319419
}
320420
delete bmpFile;
@@ -338,17 +438,13 @@ void CMenuPlayerSetup::ApplyColorToLogoPreview()
338438
{
339439
if( !stricmp( logoColorStr, L( g_LogoColors[i].name )))
340440
{
341-
logoImage.r = g_LogoColors[i].r;
342-
logoImage.g = g_LogoColors[i].g;
343-
logoImage.b = g_LogoColors[i].b;
441+
logoImage.color = &g_LogoColors[i];
344442
return;
345443
}
346444
}
347445

348446
logoColor.SetCurrentValue( L( g_LogoColors[0].name ) );
349-
logoImage.r = g_LogoColors[0].r;
350-
logoImage.g = g_LogoColors[0].g;
351-
logoImage.b = g_LogoColors[0].b;
447+
logoImage.color = &g_LogoColors[0];
352448
}
353449

354450
void CMenuPlayerSetup::WriteNewLogo( void )
@@ -386,8 +482,8 @@ void CMenuPlayerSetup::WriteNewLogo( void )
386482
return;
387483

388484
// remap logo if needed
389-
if( logoImage.r != -1 && logoImage.g != -1 && logoImage.b != -1 )
390-
bmpFile->RemapLogo( logoImage.r, logoImage.g, logoImage.b );
485+
if( logoImage.color->stripes >= 1 )
486+
bmpFile->RemapLogo( logoImage.color->stripes, logoImage.color->rgb );
391487

392488
EngFuncs::COM_SaveFile( "logos/remapped.bmp", bmpFile->GetBitmap(), bmpFile->GetBitmapHdr()->fileSize );
393489
EngFuncs::CvarSetString( "cl_logoext", "bmp" );

0 commit comments

Comments
 (0)