rodecomp/Source/Render/DX7/SurfaceDX7.cpp
ragnarok-clanker e168b4e4a6 Restore translation-unit ownership and publish verified source corrections
Owner-authorized source migration: 31 helper-only translation units were merged into their callers or existing inline headers; both build manifests updated. Includes the preserved source payload, Lua configuration matching wowdecomp, and exact malloca expansion without diagnostic pragmas.

449 native units compiled locally and 449 staged units compiled by the pinned server toolchain. No previously byte-matched function regressed. Compiler mapping diagnostics remain recorded as needs_cleanup, not accepted or peer-confirmed. Existing independent review records are preserved. README.md is intentionally unchanged.
2026-10-25 15:42:21 +00:00

297 lines
8.4 KiB
C++

#include "Render/DX7/DeviceOwnerDX7.h"
#include "Render/DX7/SurfaceDX7.h"
#include <algorithm>
#include <cstring>
namespace {
// INLINED
std::uint32_t AlignDimension(int value) {
const std::uint32_t dimension = value;
return dimension + ((0u - dimension) & 3);
}
// INLINED
DDSURFACEDESC2 Description(DeviceOwnerDX7& owner, DWORD width, DWORD height) {
DDSURFACEDESC2 description{};
description.dwSize = sizeof(description);
description.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CKSRCBLT;
description.dwWidth = width;
description.dwHeight = height;
description.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
description.ddpfPixelFormat = owner.primaryDescription.ddpfPixelFormat;
description.ddckCKSrcBlt.dwColorSpaceLowValue = description.ddpfPixelFormat.dwRBitMask | description.ddpfPixelFormat.dwBBitMask;
description.ddckCKSrcBlt.dwColorSpaceHighValue = description.ddckCKSrcBlt.dwColorSpaceLowValue;
return description;
}
// INLINED
std::uint16_t Channel(unsigned value, const DeviceOwnerDX7::Channel& channel) {
return static_cast<std::uint16_t>((value >> (channel.expansion & 31)) << (channel.shift & 31));
}
// FUNCTION: fn_01787
std::uint16_t Color(DeviceOwnerDX7& owner, unsigned red, unsigned green, unsigned blue) {
return static_cast<std::uint16_t>(Channel(red, owner.red) + Channel(green, owner.green) + Channel(blue, owner.blue));
}
}
// OFFSET: 0x00542B50
// FUNCTION: fn_01776
CSurfaceDX7::CSurfaceDX7(DeviceOwnerDX7& owner, int width, int height)
: m_owner(&owner), m_surface(nullptr), m_width(AlignDimension(width)), m_height(AlignDimension(height)) {
auto description = Description(owner, this->m_width, this->m_height);
owner.draw->CreateSurface(&description, &this->m_surface, nullptr);
}
// OFFSET: 0x00542C80
// FUNCTION: fn_01777
CSurfaceDX7::CSurfaceDX7(DeviceOwnerDX7& owner, IDirectDrawSurface7* surface) : m_owner(&owner), m_surface(nullptr), m_width(0), m_height(0) {
if (surface) {
DDSURFACEDESC2 description{};
description.dwSize = sizeof(description);
if (SUCCEEDED(surface->GetSurfaceDesc(&description))) {
this->m_width = description.dwWidth;
this->m_height = description.dwHeight;
this->m_surface = surface;
surface->AddRef();
}
}
}
// OFFSET: 0x00542DC0
// OFFSET: 0x00542E60
// FUNCTION: fn_01779
CSurfaceDX7::~CSurfaceDX7() {
if (this->m_surface) {
this->m_surface->Release();
this->m_surface = nullptr;
}
}
// OFFSET: 0x00543360
// FUNCTION: fn_01801
std::uint32_t CSurfaceDX7::Width() {
return this->m_width;
}
// OFFSET: 0x00543310
// FUNCTION: fn_01796
std::uint32_t CSurfaceDX7::Height() {
return this->m_height;
}
// OFFSET: 0x00543000
// FUNCTION: fn_01784
bool CSurfaceDX7::Resize(int width, int height) {
this->m_width = AlignDimension(width);
this->m_height = AlignDimension(height);
if (this->m_surface) {
this->m_surface->Release();
this->m_surface = nullptr;
}
auto description = Description(*this->m_owner, this->m_width, this->m_height);
return SUCCEEDED(this->m_owner->draw->CreateSurface(&description, &this->m_surface, nullptr));
}
// OFFSET: 0x00543370
// FUNCTION: fn_01802
SurfaceLock CSurfaceDX7::Lock() {
SurfaceLock output{};
if (this->m_surface) {
DDSURFACEDESC2 description{};
if (SUCCEEDED(this->m_surface->Lock(nullptr, &description, DDLOCK_WAIT, nullptr))) {
output.success = true;
output.pixels = description.lpSurface;
output.pitch = description.lPitch;
output.width = description.dwWidth;
output.height = description.dwHeight;
output.bitsPerPixel = description.ddpfPixelFormat.dwRGBBitCount;
}
}
return output;
}
// OFFSET: 0x00543710
// FUNCTION: fn_01804
void CSurfaceDX7::Unlock() {
if (this->m_surface) {
this->m_surface->Unlock(nullptr);
}
}
// OFFSET: 0x005432A0
// FUNCTION: fn_01791
bool CSurfaceDX7::GetDC(HDC* output) {
return this->m_surface && SUCCEEDED(this->m_surface->GetDC(output));
}
// OFFSET: 0x00543400
// FUNCTION: fn_01803
void CSurfaceDX7::ReleaseDC(HDC dc) {
if (this->m_surface) {
this->m_surface->ReleaseDC(dc);
}
}
// OFFSET: 0x00543730
// FUNCTION: fn_01805
void CSurfaceDX7::Upload(int x, int y, int width, int height, const std::uint32_t* pixels, int, int sourceWidth) {
if (!this->m_surface || !width || !height) {
return;
}
const unsigned stride = sourceWidth ? sourceWidth : width;
RECT rectangle{x, y, x + width, y + height};
DDSURFACEDESC2 description{};
description.dwSize = sizeof(description);
if (FAILED(this->m_surface->Lock(&rectangle, &description, DDLOCK_WAIT | DDLOCK_WRITEONLY, nullptr))) {
return;
}
const auto transparent = Color(*this->m_owner, 255, 0, 255);
auto* output = static_cast<unsigned char*>(description.lpSurface);
for (int row = 0; row < height; ++row) {
if (description.ddpfPixelFormat.dwRGBBitCount == 16) {
for (int column = 0; column < width; ++column) {
const auto pixel = pixels[column];
const auto value = Color(*this->m_owner, (pixel >> 16) & 255, (pixel >> 8) & 255, pixel & 255);
if (value != transparent) {
std::memcpy(output + column * sizeof(value), &value, sizeof(value));
}
}
} else {
for (int column = 0; column < width; ++column) {
if ((pixels[column] & 0xFFFFFF) != 0xFF00FF) {
const std::uint32_t value = pixels[column];
std::memcpy(output + column * sizeof(value), &value, sizeof(value));
}
}
}
output += description.lPitch;
pixels += stride;
}
this->m_surface->Unlock(nullptr);
}
// OFFSET: 0x00542F70
// FUNCTION: fn_01783
void CSurfaceDX7::Fill(const RECT* rectangle, std::uint32_t color) {
if (this->m_surface) {
DDBLTFX effects;
effects.dwSize = sizeof(effects);
effects.dwFillColor = Color(*this->m_owner, color & 255, (color >> 8) & 255, (color >> 16) & 255);
this->m_surface->Blt(const_cast<RECT*>(rectangle), nullptr, nullptr, DDBLT_COLORFILL | DDBLT_WAIT, &effects);
}
}
// OFFSET: 0x005430F0
// FUNCTION: fn_01785
void CSurfaceDX7::Draw(int x, int y, int width, int height, std::uint32_t) {
RECT source{0, 0, width, height};
const int right = x + width;
const int bottom = y + height;
if (right > static_cast<int>(this->m_owner->width)) {
source.right = this->m_owner->width - x;
}
if (bottom > static_cast<int>(this->m_owner->height)) {
source.bottom = this->m_owner->height - y;
}
source.left = x < 0 ? -x : 0;
source.top = y < 0 ? -y : 0;
if (source.right > source.left && source.bottom > source.top) {
this->m_owner->renderTarget->BltFast(std::max(x, 0), std::max(y, 0), this->m_surface, &source, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);
}
}
// OFFSET: 0x005431C0
// FUNCTION: fn_01786
void CSurfaceDX7::Stretch(int, int, int width, int height) {
RECT destination{0, 0, width, height};
this->m_owner->renderTarget->Blt(&destination, this->m_surface, nullptr, DDBLT_WAIT, nullptr);
}
// FUNCTION: fn_01788
DWORD DeviceOwnerDX7::BlueMask() {
return this->blueMask;
}
// FUNCTION: fn_01789
DWORD DeviceOwnerDX7::BlueExpansion() {
return this->blue.expansion;
}
// FUNCTION: fn_01790
DWORD DeviceOwnerDX7::BlueShift() {
return this->blue.shift;
}
// FUNCTION: fn_01792
IDirectDraw7* DeviceOwnerDX7::DirectDraw() {
return this->draw;
}
// FUNCTION: fn_01793
DWORD DeviceOwnerDX7::GreenMask() {
return this->greenMask;
}
// FUNCTION: fn_01794
DWORD DeviceOwnerDX7::GreenExpansion() {
return this->green.expansion;
}
// FUNCTION: fn_01795
DWORD DeviceOwnerDX7::GreenShift() {
return this->green.shift;
}
// FUNCTION: fn_01797
DWORD DeviceOwnerDX7::RedMask() {
return this->redMask;
}
// FUNCTION: fn_01798
DWORD DeviceOwnerDX7::RedExpansion() {
return this->red.expansion;
}
// FUNCTION: fn_01799
DWORD DeviceOwnerDX7::RedShift() {
return this->red.shift;
}
// FUNCTION: fn_01800
IDirectDrawSurface7* DeviceOwnerDX7::RenderTarget() {
return this->renderTarget;
}
// OFFSET: 0x00542D60
// FUNCTION: fn_01778
CSurfaceWallpaperDX7::CSurfaceWallpaperDX7(DeviceOwnerDX7& owner, int width, int height) : CSurfaceDX7(owner, width, height) {
}
// OFFSET: 0x00543990
// FUNCTION: fn_01806
void CSurfaceWallpaperDX7::Upload(int, int, int width, int height, const std::uint32_t* pixels, int, int) {
CSurfaceDX7 temporary(*this->m_owner, width, height);
temporary.Upload(0, 0, width, height, pixels, 0, 0);
this->m_surface->Blt(nullptr, temporary.m_surface, nullptr, DDBLT_WAIT, nullptr);
}