Skip to content

Commit 292c755

Browse files
authored
fix(radar): Fix Radar pixel color format for non A8R8B8G8 surfaces (TheSuperHackers#2170)
1 parent 22d757f commit 292c755

File tree

4 files changed

+132
-18
lines changed

4 files changed

+132
-18
lines changed

Core/GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ class W3DRadar : public Radar
110110
SurfaceClass *m_shroudSurface; ///< surface to shroud texture
111111
void *m_shroudSurfaceBits; ///< shroud surface bits
112112
int m_shroudSurfacePitch; ///< shroud surface pitch
113+
WW3DFormat m_shroudSurfaceFormat; ///< shroud surface format
113114
UnsignedInt m_shroudSurfacePixelSize; ///< shroud surface pixel size
114115

115116
Int m_textureWidth; ///< width for all radar textures

Core/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -700,9 +700,11 @@ void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *text
700700

701701
Player *player = rts::getObservedOrLocalPlayer();
702702

703+
SurfaceClass::SurfaceDescription surfaceDesc;
704+
surface->Get_Description(surfaceDesc);
703705
int pitch;
704706
void *pBits = surface->Lock(&pitch);
705-
const unsigned int bytesPerPixel = surface->Get_Bytes_Per_Pixel();
707+
const unsigned int bytesPerPixel = Get_Bytes_Per_Pixel(surfaceDesc.Format);
706708

707709
for( const RadarObject *rObj = listHead; rObj; rObj = rObj->friend_getNext() )
708710
{
@@ -718,7 +720,7 @@ void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *text
718720
radarPoint.y = pos->y / (m_mapExtent.height() / RADAR_CELL_HEIGHT);
719721

720722
// get the color we're going to draw in
721-
Color c = rObj->getColor();
723+
Color argbColor = rObj->getColor();
722724

723725
// adjust the alpha for stealth units so they "fade/blink" on the radar for the controller
724726
// if( obj->getRadarPriority() == RADAR_PRIORITY_LOCAL_UNIT_ONLY )
@@ -727,7 +729,7 @@ void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *text
727729
if( obj->testStatus( OBJECT_STATUS_STEALTHED ) )
728730
{
729731
UnsignedByte r, g, b, a;
730-
GameGetColorComponents( c, &r, &g, &b, &a );
732+
GameGetColorComponents( argbColor, &r, &g, &b, &a );
731733

732734
const UnsignedInt framesForTransition = LOGICFRAMES_PER_SECOND;
733735
const UnsignedByte minAlpha = 32;
@@ -737,25 +739,27 @@ void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *text
737739
a = REAL_TO_UNSIGNEDBYTE( ((alphaScale - 1.0f) * (255.0f - minAlpha)) + minAlpha );
738740
else
739741
a = REAL_TO_UNSIGNEDBYTE( (alphaScale * (255.0f - minAlpha)) + minAlpha );
740-
c = GameMakeColor( r, g, b, a );
742+
argbColor = GameMakeColor( r, g, b, a );
741743

742744
}
743745

746+
const unsigned int pixelColor = ARGB_Color_To_WW3D_Color(surfaceDesc.Format, argbColor);
747+
744748
// draw the blip, but make sure the points are legal
745749
if( legalRadarPoint( radarPoint.x, radarPoint.y ) )
746-
surface->Draw_Pixel( radarPoint.x, radarPoint.y, c, bytesPerPixel, pBits, pitch );
750+
surface->Draw_Pixel( radarPoint.x, radarPoint.y, pixelColor, bytesPerPixel, pBits, pitch );
747751

748752
radarPoint.y++;
749753
if( legalRadarPoint( radarPoint.x, radarPoint.y ) )
750-
surface->Draw_Pixel( radarPoint.x, radarPoint.y, c, bytesPerPixel, pBits, pitch );
754+
surface->Draw_Pixel( radarPoint.x, radarPoint.y, pixelColor, bytesPerPixel, pBits, pitch );
751755

752756
radarPoint.x++;
753757
if( legalRadarPoint( radarPoint.x, radarPoint.y ) )
754-
surface->Draw_Pixel( radarPoint.x, radarPoint.y, c, bytesPerPixel, pBits, pitch );
758+
surface->Draw_Pixel( radarPoint.x, radarPoint.y, pixelColor, bytesPerPixel, pBits, pitch );
755759

756760
radarPoint.y--;
757761
if( legalRadarPoint( radarPoint.x, radarPoint.y ) )
758-
surface->Draw_Pixel( radarPoint.x, radarPoint.y, c, bytesPerPixel, pBits, pitch );
762+
surface->Draw_Pixel( radarPoint.x, radarPoint.y, pixelColor, bytesPerPixel, pBits, pitch );
759763

760764
}
761765

@@ -860,6 +864,7 @@ W3DRadar::W3DRadar( void )
860864
m_shroudSurface = nullptr;
861865
m_shroudSurfaceBits = nullptr;
862866
m_shroudSurfacePitch = 0;
867+
m_shroudSurfaceFormat = WW3D_FORMAT_UNKNOWN;
863868
m_shroudSurfacePixelSize = 0;
864869

865870
m_textureWidth = RADAR_CELL_WIDTH;
@@ -1078,9 +1083,11 @@ void W3DRadar::buildTerrainTexture( TerrainLogic *terrain )
10781083
Coord3D worldPoint;
10791084
Bridge *bridge;
10801085

1086+
SurfaceClass::SurfaceDescription surfaceDesc;
1087+
surface->Get_Description(surfaceDesc);
10811088
int pitch;
10821089
void *pBits = surface->Lock(&pitch);
1083-
const unsigned int bytesPerPixel = surface->Get_Bytes_Per_Pixel();
1090+
const unsigned int bytesPerPixel = Get_Bytes_Per_Pixel(surfaceDesc.Format);
10841091

10851092
for( y = 0; y < m_textureHeight; y++ )
10861093
{
@@ -1269,7 +1276,8 @@ void W3DRadar::buildTerrainTexture( TerrainLogic *terrain )
12691276

12701277
// draw the pixel for the terrain at this point, note that because of the orientation
12711278
// of our world we draw it with positive y in the "up" direction
1272-
Color pixelColor = GameMakeColor( color.red * 255, color.green * 255, color.blue * 255, 255 );
1279+
const Color argbColor = GameMakeColor( color.red * 255, color.green * 255, color.blue * 255, 255 );
1280+
const unsigned int pixelColor = ARGB_Color_To_WW3D_Color(surfaceDesc.Format, argbColor);
12731281
surface->Draw_Pixel( x, y, pixelColor, bytesPerPixel, pBits, pitch );
12741282

12751283
}
@@ -1364,16 +1372,19 @@ void W3DRadar::setShroudLevel(Int shroudX, Int shroudY, CellShroudStatus setting
13641372
// This is expensive.
13651373
SurfaceClass* surface = m_shroudTexture->Get_Surface_Level();
13661374
DEBUG_ASSERTCRASH( surface, ("W3DRadar: Can't get surface for Shroud texture") );
1375+
SurfaceClass::SurfaceDescription surfaceDesc;
1376+
surface->Get_Description(surfaceDesc);
13671377
int pitch;
13681378
void *pBits = surface->Lock(&pitch);
1369-
const unsigned int bytesPerPixel = surface->Get_Bytes_Per_Pixel();
1370-
const Color color = GameMakeColor( 0, 0, 0, alpha );
1379+
const unsigned int bytesPerPixel = Get_Bytes_Per_Pixel(surfaceDesc.Format);
1380+
const Color argbColor = GameMakeColor( 0, 0, 0, alpha );
1381+
const unsigned int pixelColor = ARGB_Color_To_WW3D_Color(surfaceDesc.Format, argbColor);
13711382

13721383
for( Int y = radarMinY; y <= radarMaxY; ++y )
13731384
{
13741385
for( Int x = radarMinX; x <= radarMaxX; ++x )
13751386
{
1376-
surface->Draw_Pixel( x, y, color, bytesPerPixel, pBits, pitch );
1387+
surface->Draw_Pixel( x, y, pixelColor, bytesPerPixel, pBits, pitch );
13771388
}
13781389
}
13791390

@@ -1384,14 +1395,16 @@ void W3DRadar::setShroudLevel(Int shroudX, Int shroudY, CellShroudStatus setting
13841395
{
13851396
// This is cheap.
13861397
DEBUG_ASSERTCRASH(m_shroudSurfaceBits != nullptr, ("W3DRadar::setShroudLevel: m_shroudSurfaceBits is not expected null"));
1398+
DEBUG_ASSERTCRASH(m_shroudSurfaceFormat != WW3D_FORMAT_UNKNOWN, ("W3DRadar::setShroudLevel: m_shroudSurfaceFormat is not expected UNKNOWN"));
13871399
DEBUG_ASSERTCRASH(m_shroudSurfacePixelSize != 0, ("W3DRadar::setShroudLevel: m_shroudSurfacePixelSize is not expected 0"));
1388-
const Color color = GameMakeColor( 0, 0, 0, alpha );
1400+
const Color argbColor = GameMakeColor( 0, 0, 0, alpha );
1401+
const unsigned int pixelColor = ARGB_Color_To_WW3D_Color(m_shroudSurfaceFormat, argbColor);
13891402

13901403
for( Int y = radarMinY; y <= radarMaxY; ++y )
13911404
{
13921405
for( Int x = radarMinX; x <= radarMaxX; ++x )
13931406
{
1394-
m_shroudSurface->Draw_Pixel( x, y, color, m_shroudSurfacePixelSize, m_shroudSurfaceBits, m_shroudSurfacePitch );
1407+
m_shroudSurface->Draw_Pixel( x, y, pixelColor, m_shroudSurfacePixelSize, m_shroudSurfaceBits, m_shroudSurfacePitch );
13951408
}
13961409
}
13971410
}
@@ -1403,10 +1416,11 @@ void W3DRadar::beginSetShroudLevel()
14031416
m_shroudSurface = m_shroudTexture->Get_Surface_Level();
14041417
DEBUG_ASSERTCRASH( m_shroudSurface != nullptr, ("W3DRadar::beginSetShroudLevel: Can't get surface for Shroud texture") );
14051418

1406-
SurfaceClass::SurfaceDescription sd;
1407-
m_shroudSurface->Get_Description(sd);
1419+
SurfaceClass::SurfaceDescription surfaceDesc;
1420+
m_shroudSurface->Get_Description(surfaceDesc);
14081421
m_shroudSurfaceBits = m_shroudSurface->Lock(&m_shroudSurfacePitch);
1409-
m_shroudSurfacePixelSize = Get_Bytes_Per_Pixel(sd.Format);
1422+
m_shroudSurfaceFormat = surfaceDesc.Format;
1423+
m_shroudSurfacePixelSize = Get_Bytes_Per_Pixel(surfaceDesc.Format);
14101424
}
14111425

14121426
void W3DRadar::endSetShroudLevel()
@@ -1417,6 +1431,7 @@ void W3DRadar::endSetShroudLevel()
14171431
m_shroudSurface->Unlock();
14181432
m_shroudSurfaceBits = nullptr;
14191433
m_shroudSurfacePitch = 0;
1434+
m_shroudSurfaceFormat = WW3D_FORMAT_UNKNOWN;
14201435
m_shroudSurfacePixelSize = 0;
14211436
}
14221437
REF_PTR_RELEASE(m_shroudSurface);

Core/Libraries/Source/WWVegas/WW3D2/ww3dformat.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,102 @@ unsigned Get_Bytes_Per_Pixel(WW3DFormat format)
422422
return 0;
423423
}
424424

425+
unsigned ARGB_Color_To_WW3D_Color(WW3DFormat format, unsigned argb)
426+
{
427+
unsigned a = (argb >> 24) & 0xFF;
428+
unsigned r = (argb >> 16) & 0xFF;
429+
unsigned g = (argb >> 8) & 0xFF;
430+
unsigned b = (argb >> 0) & 0xFF;
431+
432+
switch (format)
433+
{
434+
case WW3D_FORMAT_R8G8B8:
435+
return (r << 16) | (g << 8) | b;
436+
437+
case WW3D_FORMAT_A8R8G8B8:
438+
return (a << 24) | (r << 16) | (g << 8) | b;
439+
440+
case WW3D_FORMAT_X8R8G8B8:
441+
return (0xFF << 24) | (r << 16) | (g << 8) | b;
442+
443+
case WW3D_FORMAT_R5G6B5:
444+
return ((r >> 3) << 11) |
445+
((g >> 2) << 5) |
446+
((b >> 3) << 0);
447+
448+
case WW3D_FORMAT_X1R5G5B5:
449+
return ( 1 << 15) |
450+
((r >> 3) << 10) |
451+
((g >> 3) << 5) |
452+
((b >> 3) << 0);
453+
454+
case WW3D_FORMAT_A1R5G5B5:
455+
return ((a >> 7) << 15) |
456+
((r >> 3) << 10) |
457+
((g >> 3) << 5) |
458+
((b >> 3) << 0);
459+
460+
case WW3D_FORMAT_A4R4G4B4:
461+
return ((a >> 4) << 12) |
462+
((r >> 4) << 8) |
463+
((g >> 4) << 4) |
464+
((b >> 4) << 0);
465+
466+
case WW3D_FORMAT_R3G3B2:
467+
return ((r >> 5) << 5) |
468+
((g >> 5) << 2) |
469+
((b >> 6) << 0);
470+
471+
case WW3D_FORMAT_A8:
472+
return a;
473+
474+
case WW3D_FORMAT_A8R3G3B2:
475+
return ( a << 8) |
476+
((r >> 5) << 5) |
477+
((g >> 5) << 2) |
478+
((b >> 6) << 0);
479+
480+
case WW3D_FORMAT_X4R4G4B4:
481+
return ( 0xF << 12) |
482+
((r >> 4) << 8) |
483+
((g >> 4) << 4) |
484+
((b >> 4) << 0);
485+
486+
case WW3D_FORMAT_L8:
487+
{
488+
unsigned l = (r * 77 + g * 150 + b * 29) >> 8;
489+
return l;
490+
}
491+
492+
case WW3D_FORMAT_A8L8:
493+
{
494+
unsigned l = (r * 77 + g * 150 + b * 29) >> 8;
495+
return (a << 8) | l;
496+
}
497+
498+
case WW3D_FORMAT_A4L4:
499+
{
500+
unsigned l = (r * 77 + g * 150 + b * 29) >> 8;
501+
return ((a >> 4) << 4) | (l >> 4);
502+
}
503+
504+
// Palettized, bump-map, and compressed formats
505+
// cannot be represented by a single ARGB color
506+
case WW3D_FORMAT_P8:
507+
case WW3D_FORMAT_A8P8:
508+
case WW3D_FORMAT_U8V8:
509+
case WW3D_FORMAT_L6V5U5:
510+
case WW3D_FORMAT_X8L8V8U8:
511+
case WW3D_FORMAT_DXT1:
512+
case WW3D_FORMAT_DXT2:
513+
case WW3D_FORMAT_DXT3:
514+
case WW3D_FORMAT_DXT4:
515+
case WW3D_FORMAT_DXT5:
516+
default:
517+
return 0;
518+
}
519+
}
520+
425521
unsigned Get_Num_Depth_Bits(WW3DZFormat zformat)
426522
{
427523
switch (zformat)

Core/Libraries/Source/WWVegas/WW3D2/ww3dformat.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ WW3DFormat Get_Valid_Texture_Format(WW3DFormat format,bool is_compression_allowe
195195

196196
unsigned Get_Bytes_Per_Pixel(WW3DFormat format);
197197

198+
unsigned ARGB_Color_To_WW3D_Color(WW3DFormat format, unsigned argb);
199+
198200
void Get_WW3D_Format_Name(WW3DFormat format, StringClass& name);
199201
void Get_WW3D_ZFormat_Name(WW3DZFormat format, StringClass& name);
200202

0 commit comments

Comments
 (0)