mirror of
https://github.com/BodbDearg/PsyDoom.git
synced 2025-02-21 13:43:09 +00:00
Remove the use of bitfields for Gpu::Color16
. These were a portability hazard, since the bitfield layout is compiler dependent.
This commit is contained in:
parent
52b3028fd6
commit
74b31bdbaf
@ -1,5 +1,4 @@
|
||||
- Implement integer scaling.
|
||||
- Fix reliance on bitfields for 16-bit pixels via 'Color16' (bitfield order implementation dependant).
|
||||
- Fix reliance on bitfields for network code via 'TickInputs' (bitfield order implementation dependant).
|
||||
- Fix reliance on bitfields for 'spu::AdsrEnvelope' (bitfield order implementation dependant).
|
||||
- Linux support.
|
||||
|
@ -232,9 +232,9 @@ void VideoBackend_SDL::copyPsxToSdlFramebufferTexture() noexcept {
|
||||
// Note: don't bother doing multiple pixels at a time - compiler is smart and already optimizes this to use SIMD
|
||||
for (uint32_t x = xStart; x < xEnd; ++x, ++pDstPixel) {
|
||||
const Gpu::Color16 srcPixel = rowPixels[x];
|
||||
const uint32_t r = (uint32_t) srcPixel.comp.r << 3;
|
||||
const uint32_t g = (uint32_t) srcPixel.comp.g << 3;
|
||||
const uint32_t b = (uint32_t) srcPixel.comp.b << 3;
|
||||
const uint32_t r = (uint32_t) srcPixel.getR() << 3;
|
||||
const uint32_t g = (uint32_t) srcPixel.getG() << 3;
|
||||
const uint32_t b = (uint32_t) srcPixel.getB() << 3;
|
||||
|
||||
*pDstPixel = (0xFF000000 | (b << 16) | (g << 8 ) | (r << 0));
|
||||
}
|
||||
|
@ -261,11 +261,11 @@ Color16 color24FTo16(const Color24F colorIn) noexcept {
|
||||
constexpr uint32_t COLOR_NORMALIZE = (bIsTextured) ? 128 : 255;
|
||||
constexpr uint32_t ROUND_UP = (bIsTextured) ? 0 : 128;
|
||||
|
||||
Color16 colorOut;
|
||||
colorOut.comp.r = (uint16_t) std::min(((uint32_t) colorIn.comp.r * 31u + ROUND_UP) / COLOR_NORMALIZE, 31u);
|
||||
colorOut.comp.g = (uint16_t) std::min(((uint32_t) colorIn.comp.g * 31u + ROUND_UP) / COLOR_NORMALIZE, 31u);
|
||||
colorOut.comp.b = (uint16_t) std::min(((uint32_t) colorIn.comp.b * 31u + ROUND_UP) / COLOR_NORMALIZE, 31u);
|
||||
return colorOut;
|
||||
return Color16::make(
|
||||
(uint16_t) std::min(((uint32_t) colorIn.comp.r * 31u + ROUND_UP) / COLOR_NORMALIZE, 31u),
|
||||
(uint16_t) std::min(((uint32_t) colorIn.comp.g * 31u + ROUND_UP) / COLOR_NORMALIZE, 31u),
|
||||
(uint16_t) std::min(((uint32_t) colorIn.comp.b * 31u + ROUND_UP) / COLOR_NORMALIZE, 31u)
|
||||
);
|
||||
}
|
||||
|
||||
// Instantiate the variants of this function
|
||||
@ -278,12 +278,12 @@ template Color16 color24FTo16<DrawMode::TexturedBlended>(const Color24F colorIn)
|
||||
// Modulate a 16-bit color by a 24-bit one where the components are in 1.7 fixed point format
|
||||
//------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Color16 colorMul(const Color16 color1, const Color24F color2) noexcept {
|
||||
Color16 out;
|
||||
out.comp.r = (uint16_t) std::min((color1.comp.r * color2.comp.r) >> 7, 31);
|
||||
out.comp.g = (uint16_t) std::min((color1.comp.g * color2.comp.g) >> 7, 31);
|
||||
out.comp.b = (uint16_t) std::min((color1.comp.b * color2.comp.b) >> 7, 31);
|
||||
out.comp.t = color1.comp.t;
|
||||
return out;
|
||||
return Color16::make(
|
||||
(uint16_t) std::min((color1.getR() * color2.comp.r) >> 7, 31),
|
||||
(uint16_t) std::min((color1.getG() * color2.comp.g) >> 7, 31),
|
||||
(uint16_t) std::min((color1.getB() * color2.comp.b) >> 7, 31),
|
||||
color1.getT()
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -294,27 +294,35 @@ Color16 colorBlend(const Color16 bg, const Color16 fg, const BlendMode mode) noe
|
||||
|
||||
switch (mode) {
|
||||
case BlendMode::Alpha50:
|
||||
result.comp.r = (uint16_t)((bg.comp.r + fg.comp.r) >> 1);
|
||||
result.comp.g = (uint16_t)((bg.comp.g + fg.comp.g) >> 1);
|
||||
result.comp.b = (uint16_t)((bg.comp.b + fg.comp.b) >> 1);
|
||||
result.setRGB(
|
||||
(uint16_t)((bg.getR() + fg.getR()) >> 1),
|
||||
(uint16_t)((bg.getG() + fg.getG()) >> 1),
|
||||
(uint16_t)((bg.getB() + fg.getB()) >> 1)
|
||||
);
|
||||
break;
|
||||
|
||||
case BlendMode::Add:
|
||||
result.comp.r = (uint16_t) std::min(bg.comp.r + fg.comp.r, 31);
|
||||
result.comp.g = (uint16_t) std::min(bg.comp.g + fg.comp.g, 31);
|
||||
result.comp.b = (uint16_t) std::min(bg.comp.b + fg.comp.b, 31);
|
||||
result.setRGB(
|
||||
(uint16_t) std::min(bg.getR() + fg.getR(), 31),
|
||||
(uint16_t) std::min(bg.getG() + fg.getG(), 31),
|
||||
(uint16_t) std::min(bg.getB() + fg.getB(), 31)
|
||||
);
|
||||
break;
|
||||
|
||||
case BlendMode::Subtract:
|
||||
result.comp.r = (uint16_t) std::max((int32_t) bg.comp.r - (int32_t) fg.comp.r, 0);
|
||||
result.comp.g = (uint16_t) std::max((int32_t) bg.comp.g - (int32_t) fg.comp.g, 0);
|
||||
result.comp.b = (uint16_t) std::max((int32_t) bg.comp.b - (int32_t) fg.comp.b, 0);
|
||||
result.setRGB(
|
||||
(uint16_t) std::max((int32_t) bg.getR() - (int32_t) fg.getR(), 0),
|
||||
(uint16_t) std::max((int32_t) bg.getG() - (int32_t) fg.getG(), 0),
|
||||
(uint16_t) std::max((int32_t) bg.getB() - (int32_t) fg.getB(), 0)
|
||||
);
|
||||
break;
|
||||
|
||||
case BlendMode::Add25:
|
||||
result.comp.r = (uint16_t) std::min(bg.comp.r + (fg.comp.r >> 2), 31);
|
||||
result.comp.g = (uint16_t) std::min(bg.comp.g + (fg.comp.g >> 2), 31);
|
||||
result.comp.b = (uint16_t) std::min(bg.comp.b + (fg.comp.b >> 2), 31);
|
||||
result.setRGB(
|
||||
(uint16_t) std::min(bg.getR() + (fg.getR() >> 2), 31),
|
||||
(uint16_t) std::min(bg.getG() + (fg.getG() >> 2), 31),
|
||||
(uint16_t) std::min(bg.getB() + (fg.getB() >> 2), 31)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -835,10 +843,11 @@ static void draw(Core& core, const DrawTriangleGouraud& triangle) noexcept {
|
||||
}
|
||||
else {
|
||||
// Not doing texture mapping: foreground color is just the interpolated color
|
||||
fgColor.comp.r = std::min<uint16_t>(((uint16_t) gColorR + 4) >> 3, 31u);
|
||||
fgColor.comp.g = std::min<uint16_t>(((uint16_t) gColorG + 4) >> 3, 31u);
|
||||
fgColor.comp.b = std::min<uint16_t>(((uint16_t) gColorB + 4) >> 3, 31u);
|
||||
fgColor.comp.t = 0;
|
||||
fgColor = Color16::make(
|
||||
std::min<uint16_t>(((uint16_t) gColorR + 4) >> 3, 31u),
|
||||
std::min<uint16_t>(((uint16_t) gColorG + 4) >> 3, 31u),
|
||||
std::min<uint16_t>(((uint16_t) gColorB + 4) >> 3, 31u)
|
||||
);
|
||||
}
|
||||
|
||||
// Do blending with the background if that is enabled
|
||||
@ -1242,10 +1251,11 @@ void draw(Core& core, const DrawWallColGouraud& col) noexcept {
|
||||
fgColor = colorMul(fgColor, colColor);
|
||||
} else {
|
||||
// Not doing texture mapping: foreground color is just the interpolated color
|
||||
fgColor.comp.r = std::min<uint16_t>(((uint16_t) gColorR + 4) >> 3, 31u);
|
||||
fgColor.comp.g = std::min<uint16_t>(((uint16_t) gColorG + 4) >> 3, 31u);
|
||||
fgColor.comp.b = std::min<uint16_t>(((uint16_t) gColorB + 4) >> 3, 31u);
|
||||
fgColor.comp.t = 0;
|
||||
fgColor = Color16::make(
|
||||
std::min<uint16_t>(((uint16_t) gColorR + 4) >> 3, 31u),
|
||||
std::min<uint16_t>(((uint16_t) gColorG + 4) >> 3, 31u),
|
||||
std::min<uint16_t>(((uint16_t) gColorB + 4) >> 3, 31u)
|
||||
);
|
||||
}
|
||||
|
||||
// Do blending with the background if that is enabled
|
||||
|
@ -67,24 +67,38 @@ union Color24F {
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Represents a 15-bit BGR555 color used by the GPU plus 1 bit that says whether blending is enabled for the pixel.
|
||||
// Represents a 15-bit TBGR1555 color used by the GPU.
|
||||
// This is used as a dest/output format for the framebuffer and also as an input format for 16-bit textures & CLUTs.
|
||||
// Note: the top bit (T) is the PlayStation 'semi-transparency' bit.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
union Color16 {
|
||||
// The individual components of the color
|
||||
struct {
|
||||
uint16_t r : 5;
|
||||
uint16_t g : 5;
|
||||
uint16_t b : 5;
|
||||
uint16_t t : 1; // High bit: blending/semi-transparency flag. If set then blend the pixel, if drawing a blended primitive.
|
||||
} comp;
|
||||
|
||||
// The full 16-bits of the color
|
||||
struct Color16 {
|
||||
uint16_t bits;
|
||||
|
||||
inline constexpr uint16_t getR() const noexcept { return bits & 0x1F; }
|
||||
inline constexpr uint16_t getG() const noexcept { return (bits >> 5) & 0x1F; }
|
||||
inline constexpr uint16_t getB() const noexcept { return (bits >> 10) & 0x1F; }
|
||||
inline constexpr uint16_t getT() const noexcept { return bits >> 15; }
|
||||
|
||||
inline constexpr Color16() noexcept : bits(0) {}
|
||||
inline constexpr Color16(const uint16_t bits) noexcept : bits(bits) {}
|
||||
inline constexpr operator uint16_t() const noexcept { return bits; }
|
||||
|
||||
// Set the color values using RGB555 components that are assumed to be in range
|
||||
void setRGB(const uint16_t r5, const uint16_t g5, const uint16_t b5) noexcept {
|
||||
bits &= 0x8000;
|
||||
bits |= (r5 | (g5 << 5) | (b5 << 10));
|
||||
}
|
||||
|
||||
// Makes a color from the individual components.
|
||||
// Note: the components are already assumed to be in range: 5-bits for RGB and 1-bit for semi-transparency.
|
||||
static inline constexpr Color16 make(const uint16_t r5, const uint16_t g5, const uint16_t b5, const uint16_t t1) noexcept {
|
||||
return Color16(r5 | (g5 << 5) | (b5 << 10) | (t1 << 15));
|
||||
}
|
||||
|
||||
// Same as 'make' but with the semi transparency flag not set (RGB only)
|
||||
static inline constexpr Color16 make(const uint16_t r5, const uint16_t g5, const uint16_t b5) noexcept {
|
||||
return Color16(r5 | (g5 << 5) | (b5 << 10));
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user