- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
258 lines
6.6 KiB
C++
258 lines
6.6 KiB
C++
//----------------------------------------------------------------------------
|
|
// ObjectWindows
|
|
// (C) Copyright 1992, 1994 by Borland International, All Rights Reserved
|
|
//
|
|
// Implementation of GDI Bitmap object class
|
|
//----------------------------------------------------------------------------
|
|
#include <owl/owlpch.h>
|
|
#include <owl/gdiobjec.h>
|
|
#include <owl/metafile.h>
|
|
#include <owl/clipboar.h>
|
|
|
|
DIAG_DECLARE_GROUP(OwlGDI); // General GDI diagnostic group
|
|
DIAG_DECLARE_GROUP(OwlGDIOrphan); // Orphan control tracing group
|
|
|
|
//
|
|
// Construct an alias TBitmap for an existing bitmap handle
|
|
//
|
|
TBitmap::TBitmap(HBITMAP handle, TAutoDelete autoDelete)
|
|
:
|
|
TGdiObject(handle, autoDelete)
|
|
{
|
|
#if !defined(NO_GDI_ORPHAN_CONTROL)
|
|
if (ShouldDelete)
|
|
OBJ_REF_ADD(Handle, Bitmap);
|
|
#endif
|
|
}
|
|
|
|
TBitmap::TBitmap()
|
|
:
|
|
TGdiObject()
|
|
{
|
|
}
|
|
|
|
TBitmap::TBitmap(const TClipboard& clipboard)
|
|
:
|
|
TGdiObject(clipboard.GetClipboardData(CF_BITMAP))
|
|
{
|
|
OBJ_REF_ADD(Handle, Bitmap);
|
|
OBJ_REF_INC(Handle);
|
|
}
|
|
|
|
TBitmap::TBitmap(int width, int height, uint8 planes, uint8 bitCount, const void far* bits)
|
|
{
|
|
Handle = ::CreateBitmap(width, height, planes, bitCount, bits);
|
|
WARNX(OwlGDI, !Handle, 0, "Cannot create bitmap (" << width << "x" <<
|
|
height << "x" << planes << ")");
|
|
CheckValid();
|
|
OBJ_REF_ADD(Handle, Bitmap);
|
|
}
|
|
|
|
TBitmap::TBitmap(const BITMAP far* bitmap)
|
|
{
|
|
PRECONDITION(bitmap);
|
|
Handle = ::CreateBitmapIndirect((LPBITMAP)bitmap); // API cast
|
|
WARNX(OwlGDI, !Handle, 0, "Cannot create bitmap from BITMAP @" <<
|
|
hex << uint32(LPVOID(bitmap)));
|
|
CheckValid();
|
|
OBJ_REF_ADD(Handle, Bitmap);
|
|
}
|
|
|
|
TBitmap::TBitmap(const TDC& dc, int width, int height, bool discardable)
|
|
{
|
|
if (discardable) {
|
|
Handle = ::CreateDiscardableBitmap(dc, width, height);
|
|
WARNX(OwlGDI, !Handle, 0, "Cannot create discardable bitmap (" << width <<
|
|
"x" << height << ") for " << hex << (uint)(HDC)dc);
|
|
}
|
|
else {
|
|
Handle = ::CreateCompatibleBitmap(dc, width, height);
|
|
WARNX(OwlGDI, !Handle, 0, "Cannot create compatible bitmap (" << width <<
|
|
"x" << height << ") for " << hex << (uint)(HDC)dc);
|
|
}
|
|
CheckValid();
|
|
OBJ_REF_ADD(Handle, Bitmap);
|
|
}
|
|
|
|
TBitmap::TBitmap(const TDC& dc, const TDib& dib, uint32 usage)
|
|
{
|
|
Handle = ::CreateDIBitmap(dc,
|
|
(BITMAPINFOHEADER far*)dib.GetInfoHeader(),
|
|
usage, (const uint8 FAR*)dib.GetBits(),
|
|
(BITMAPINFO far*)dib.GetInfo(),
|
|
dib.Usage());
|
|
// API casts
|
|
WARNX(OwlGDI, !Handle, 0, "Cannot create bitmap from DIB " << hex <<
|
|
(uint)(HANDLE)dib << " for " << (uint)(HDC)dc);
|
|
CheckValid();
|
|
OBJ_REF_ADD(Handle, Bitmap);
|
|
}
|
|
|
|
TBitmap::TBitmap(HINSTANCE instance, TResId resId)
|
|
{
|
|
Handle = ::LoadBitmap(instance, resId);
|
|
WARNX(OwlGDI, !Handle, 0, "Cannot load bitmap " << resId << " from " <<
|
|
hex << (uint)instance);
|
|
CheckValid();
|
|
OBJ_REF_ADD(Handle, Bitmap);
|
|
}
|
|
|
|
//
|
|
// Copy constructor, duplicates a bitmap, bits and all
|
|
//
|
|
TBitmap::TBitmap(const TBitmap& src)
|
|
{
|
|
Handle = 0;
|
|
Create(src);
|
|
}
|
|
|
|
//
|
|
// Construct a bitmap by playing a metafile into it
|
|
//
|
|
TBitmap::TBitmap(const TMetaFilePict& metaFile, TPalette& palette, const TSize& defSize)
|
|
{
|
|
// Adjust size to final metafile size as needed
|
|
//
|
|
TMemoryDC memDC;
|
|
TSize size = metaFile.CalcPlaySize(memDC, defSize);
|
|
|
|
// Create bitmap, either mono or screen compatible
|
|
//
|
|
uint16 nColors;
|
|
palette.GetObject(nColors);
|
|
if (nColors > 2) {
|
|
TScreenDC dc;
|
|
Handle = ::CreateCompatibleBitmap(dc, size.cx, size.cy);
|
|
}
|
|
else
|
|
Handle = ::CreateBitmap(size.cx, size.cy, 1, 1, 0);
|
|
|
|
CheckValid();
|
|
OBJ_REF_ADD(Handle, Bitmap);
|
|
|
|
// clear bitmap, then play metafile onto it
|
|
//
|
|
memDC.SelectObject(*this);
|
|
|
|
memDC.SelectStockObject(WHITE_BRUSH);
|
|
memDC.PatBlt(0, 0, size.cx, size.cy);
|
|
memDC.SelectObject(palette, false);
|
|
|
|
metaFile.PlayOnto(memDC, size);
|
|
}
|
|
|
|
//
|
|
// Construct a Bitmap given a handle to a TDib, and a pointer to a TPalette.
|
|
// If the palette is not supplied, a temp one is created and destroyed.
|
|
//
|
|
TBitmap::TBitmap(const TDib& dib, const TPalette* palette)
|
|
{
|
|
if (palette)
|
|
Create(dib, *palette);
|
|
else
|
|
Create(dib, TPalette(dib));
|
|
}
|
|
|
|
//
|
|
// Get and return specific information about the bitmap using GDI's GetObject
|
|
//
|
|
int
|
|
TBitmap::Width() const
|
|
{
|
|
BITMAP bm;
|
|
GetObject(bm);
|
|
return bm.bmWidth;
|
|
}
|
|
|
|
int
|
|
TBitmap::Height() const
|
|
{
|
|
BITMAP bm;
|
|
GetObject(bm);
|
|
return bm.bmHeight;
|
|
}
|
|
|
|
uint8
|
|
TBitmap::Planes() const
|
|
{
|
|
BITMAP bm;
|
|
GetObject(bm);
|
|
return bm.bmPlanes;
|
|
}
|
|
|
|
uint8
|
|
TBitmap::BitsPixel() const
|
|
{
|
|
BITMAP bm;
|
|
GetObject(bm);
|
|
return bm.bmBitsPixel;
|
|
}
|
|
|
|
//
|
|
// Put a device-dependent bitmap on the clipboard as a (DD)BITMAP. Clipboard
|
|
// assumes ownership of the actual bitmap.
|
|
//
|
|
void
|
|
TBitmap::ToClipboard(TClipboard& clipboard)
|
|
{
|
|
clipboard.SetClipboardData(CF_BITMAP, Handle);
|
|
ShouldDelete = false;
|
|
OBJ_REF_REMOVE(Handle);
|
|
}
|
|
|
|
//
|
|
// Create a bitmap & get its handle, given a dib and a palette
|
|
// Used by ctors here and in derived classes. Assumes Handle can be
|
|
// written over, & adds handle to reference container.
|
|
//
|
|
void
|
|
TBitmap::Create(const TDib& dib, const TPalette& palette)
|
|
{
|
|
TScreenDC dc;
|
|
dc.SelectObject(palette, false);
|
|
dc.RealizePalette();
|
|
|
|
Handle = ::CreateDIBitmap(
|
|
dc,
|
|
(LPBITMAPINFOHEADER)dib.GetInfoHeader(),
|
|
CBM_INIT,
|
|
(const uint8 far*)dib.GetBits(),
|
|
(LPBITMAPINFO)dib.GetInfo(),
|
|
dib.Usage()
|
|
); // API type casts
|
|
|
|
CheckValid();
|
|
OBJ_REF_ADD(Handle, Bitmap);
|
|
}
|
|
|
|
//
|
|
// Create a bitmap & get its handle, given an other bitmap
|
|
// Used by ctors here and in derived classes. Assumes Handle can be
|
|
// written over, & adds handle to reference container.
|
|
//
|
|
void
|
|
TBitmap::Create(const TBitmap& src)
|
|
{
|
|
TMemoryDC memDC1;
|
|
TMemoryDC memDC2;
|
|
|
|
BITMAP bm;
|
|
src.GetObject(bm);
|
|
if (bm.bmPlanes != 1 || bm.bmBitsPixel != 1) {
|
|
// create a color bitmap (Assume screen compatible)
|
|
TScreenDC dc;
|
|
Handle = ::CreateCompatibleBitmap(dc, bm.bmWidth, bm.bmHeight);
|
|
}
|
|
else
|
|
// create a mono bitmap
|
|
Handle = ::CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, 0);
|
|
|
|
CheckValid();
|
|
OBJ_REF_ADD(Handle, Bitmap);
|
|
|
|
memDC1.SelectObject(src);
|
|
memDC2.SelectObject(*this);
|
|
memDC2.BitBlt(TRect(TPoint(0, 0), TSize(bm.bmWidth, bm.bmHeight)),
|
|
memDC1, TPoint(0, 0), SRCCOPY);
|
|
}
|