Files
TeslaRel410/BORLAND/BC45/EXAMPLES/OWL/OWLAPPS/MTHREAD/ARTY.CPP
T
CydandClaude Fable 5 63312e07f9 source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived
- 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>
2026-07-19 07:33:26 -05:00

363 lines
9.3 KiB
C++

//----------------------------------------------------------------------------
// ObjectWindows - (C) Copyright 1991, 1993 by Borland International
// Multi-thread arty demo window object
//----------------------------------------------------------------------------
#include <owl\owlpch.h>
#include <owl\dc.h>
#include <owl\static.h>
#include "arty.h" // class definition for TArtyWindow
#include "artypriv.h" // internal component classes of TArtyWindow
#include <stdlib.h>
IMPLEMENT_CASTABLE1(TArtyWindow, TBaseDemoWindow);
//---------- TList ----------------------------------------------
// The low-level line draw routine
//
static void
LineDraw(TDC& dc, int x1, int y1, int x2, int y2)
{
dc.MoveTo(x1, y1);
dc.LineTo(x2, y2);
}
// Initialize the list-of-lines object
//
TList::TList(int _max)
{
MaxLines = min(_max, MaxLineCount);
CurrentLine = 1;
Xmax = 0;
Ymax = 0;
ColorDuration = MaxColorDuration;
IncrementCount = 0;
MaxDelta = 10;
PenColor = TColor(random(256), random(256), random(256));
}
// Keep X within range, and reverse Delta if necessary to do so
//
void
TList::AdjustX(int& x, int& deltaX)
{
int testX = x + deltaX;
if (testX < 1 || testX > Xmax) {
testX = x;
deltaX = -deltaX;
}
x = testX;
}
// Keep Y within range, and reverse Delta if necessary to do so
//
void
TList::AdjustY(int& y, int& deltaY)
{
int testY = y + deltaY;
if (testY < 1 || testY > Ymax) {
testY = y;
deltaY = -deltaY;
}
y = testY;
}
// Clear the array of lines
//
void
TList::ResetLines()
{
int startX = Xmax / 2;
int startY = Ymax / 2;
for (int i = 0; i < MaxLines; i++) {
Line[i].LX1 = startX;
Line[i].LX2 = startX;
Line[i].LY1 = startY;
Line[i].LY2 = startY;
Line[i].Color = 0;
}
X1 = startX;
X2 = startX;
Y1 = startY;
Y2 = startY;
}
// Scale the old line coordinates to the new Xmax and Ymax coordinates.
// The new Xmax and new Ymax are passed in as parameters so we can
// calculate the scaling ratios.
//
#define ScaleX( val ) val = (val*newXmax)/Xmax
#define ScaleY( val ) val = (val*newYmax)/Ymax
void
TList::ScaleTo(int newXmax, int newYmax)
{
if (!Xmax || !Ymax) { // at startup, Xmax and Ymax are zero
Xmax = newXmax;
Ymax = newYmax;
ResetLines();
} else {
ScaleX(X1);
ScaleX(X2);
ScaleY(Y1);
ScaleY(Y2);
for (int i = 0; i < MaxLines; i++) {
ScaleX(Line[i].LX1);
ScaleX(Line[i].LX2);
ScaleY(Line[i].LY1);
ScaleY(Line[i].LY2);
}
}
Xmax = newXmax;
Ymax = newYmax;
}
// The high-level Draw method of the object.
//
void
TList::DrawLine(TDC& dc, int index)
{
TPen pen(Line[index].Color);
dc.SelectObject(pen);
LineDraw(dc, Line[index].LX1, Line[index].LY1,
Line[index].LX2, Line[index].LY2);
dc.RestorePen();
}
// The high-level draw which erases a line.
//
void TList::EraseLine(TDC& dc, int index)
{
dc.SelectStockObject(BLACK_PEN);
LineDraw(dc, Line[index].LX1, Line[index].LY1,
Line[index].LX2, Line[index].LY2);
}
// Redraw all the lines in the array.
//
void
TList::Redraw(TDC& dc)
{
for (int i = 0; i < MaxLines; i++)
DrawLine(dc, i);
}
// Reset the color counter and pick a random color.
//
void
TList::SelectNewColor()
{
ColorDuration = MaxColorDuration;
PenColor = TColor(random(256), random(256), random(256));
}
// Pick random directional deltas and reset the delta counter.
//
void
TList::SelectNewDeltaValues()
{
DeltaX1 = random(MaxDelta) - MaxDelta/2;
DeltaX2 = random(MaxDelta) - MaxDelta/2;
DeltaY1 = random(MaxDelta) - MaxDelta/2;
DeltaY2 = random(MaxDelta) - MaxDelta/2;
IncrementCount = 2 * (1 + random(10));
}
// Process the movement of one line.
//
void
TList::LineTick(TDC& dc)
{
EraseLine(dc, CurrentLine);
if (ColorDuration < 0)
SelectNewColor();
if (!IncrementCount)
SelectNewDeltaValues();
AdjustX(X1, DeltaX1);
AdjustX(X2, DeltaX2);
AdjustY(Y1, DeltaY1);
AdjustY(Y2, DeltaY2);
Line[CurrentLine].LX1 = X1;
Line[CurrentLine].LX2 = X2;
Line[CurrentLine].LY1 = Y1;
Line[CurrentLine].LY2 = Y2;
Line[CurrentLine].Color = PenColor;
DrawLine(dc, CurrentLine);
CurrentLine++;
if (CurrentLine >= MaxLines)
CurrentLine = 1;
ColorDuration--;
IncrementCount--;
}
//------------ TQuadList ----------------------------------------
// Draw the line and 3 reflections of it.
//
void
TQuadList::DrawLine(TDC& dc, int index)
{
TPen pen(Line[index].Color);
dc.SelectObject(pen);
LineDraw(dc, Line[index].LX1, Line[index].LY1,
Line[index].LX2, Line[index].LY2);
LineDraw(dc, Xmax - Line[index].LX1, Line[index].LY1,
Xmax - Line[index].LX2, Line[index].LY2);
LineDraw(dc, Line[index].LX1, Ymax - Line[index].LY1,
Line[index].LX2, Ymax - Line[index].LY2);
LineDraw(dc, Xmax - Line[index].LX1, Ymax - Line[index].LY1,
Xmax - Line[index].LX2, Ymax - Line[index].LY2);
dc.RestorePen();
}
// Erase the line and 3 reflections of it.
//
void
TQuadList::EraseLine(TDC& dc, int index)
{
dc.SelectStockObject(BLACK_PEN);
LineDraw(dc, Line[index].LX1, Line[index].LY1,
Line[index].LX2, Line[index].LY2);
LineDraw(dc, Xmax - Line[index].LX1, Line[index].LY1,
Xmax - Line[index].LX2, Line[index].LY2);
LineDraw(dc, Line[index].LX1, Ymax - Line[index].LY1,
Line[index].LX2, Ymax - Line[index].LY2);
LineDraw(dc, Xmax - Line[index].LX1, Ymax - Line[index].LY1,
Xmax - Line[index].LX2, Ymax - Line[index].LY2);
}
//----------- TArtyWindow ------------------------------------------
DEFINE_RESPONSE_TABLE1(TArtyWindow, TBaseDemoWindow)
EV_WM_LBUTTONDOWN,
EV_WM_RBUTTONDOWN,
EV_WM_SIZE,
END_RESPONSE_TABLE;
TArtyWindow::TArtyWindow() : TBaseDemoWindow()
{
StaticControl = new TStatic(this, 100,
"Press Left Button to pause, Right Button to Clear",10,10,10,10,0);
Iconized = FALSE;
TextHeight = 20;
Paused = FALSE;
// Initialize two line list objects:
// BigLineList is the 4-reflection artwork that is displayed in
// a full sized window. Mouse clicks will pause or clear
// the display, and the line list will be scaled to the
// new window coordinates when the window is resized.
//
// IconicLineList is a smaller list implementing a single-line
// quark to display in the iconized window region. Since
// mouse clicks are not sent to iconized windows, the icon
// cannot be paused or cleared, and since there is only one
// icon window size, scaling the lines to new coordinates
// has no visual effect.
//
// The List pointer will be toggled between the two line list
// objects: when the window is iconized, List will point to the
// IconicLineList object. When the window is restored to full
// size, List will be made to point to the BigLineList object.
// This is so the window routines don't have to know which kind
// of list they're dealing with. Keyword: polymorphism.
BigLineList = new TQuadList(MaxLineCount);
IconicLineList = new TList(MaxIconicLineCount);
List = BigLineList;
SetBkgndColor(TColor::Black);
Start();
}
// Dispose of the objects that this window object created. There's
// no need to dispose the List pointer, since it will only point to
// one of these two objects which are being disposed by their
// primary pointers
//
TArtyWindow::~TArtyWindow()
{
delete BigLineList;
delete IconicLineList;
}
// When the window is resized, scale the line list to fit the new
// window extent, or switch between full size and iconized window
// states.
//
void
TArtyWindow::EvSize(UINT sizeType, TSize& size)
{
TBaseDemoWindow::EvSize(sizeType, size);
// Force Windows to repaint the entire window region
Invalidate(TRUE);
int newXmax = size.cx;
int newYmax = size.cy;
if (sizeType == SIZE_MINIMIZED) {
if (!Iconized) {
Iconized = TRUE;
List = IconicLineList;
}
} else {
if (Iconized) {
Iconized = FALSE;
List = BigLineList;
}
newYmax -= TextHeight; // allow room for the text at the bottom
}
List->ScaleTo(newXmax, newYmax); // scale the lines in the list
if (StaticControl)
StaticControl->MoveWindow(0, newYmax, newXmax, TextHeight, TRUE);
}
// Toggle the window's Paused status. Since the window will
// not receive mouse clicks when iconized, this will not pause the
// iconized lines display.
//
void
TArtyWindow::EvLButtonDown(UINT, TPoint&)
{
Paused = !Paused;
}
// Clear the line list when the user presses the right mouse
// button. Same comments as above on iconized windows.
//
void
TArtyWindow::EvRButtonDown(UINT, TPoint&)
{
Invalidate(TRUE);
List->ResetLines();
}
// When the window is resized, or some other window blots out part
// of our client area, redraw the entire line list.
//
void
TArtyWindow::Paint(TDC& dc, BOOL, TRect&)
{
List->Redraw(dc);
}
// Fetch a device context, pass it to the line list object, then
// release the device context back to Windows.
//
void
TArtyWindow::DoRun()
{
if( !Paused )
List->LineTick(TClientDC(Iconized ? Parent->HWindow : HWindow));
}