- 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>
361 lines
8.4 KiB
C++
361 lines
8.4 KiB
C++
//----------------------------------------------------------------------------
|
|
// ObjectWindows - (C) Copyright 1991, 1993 by Borland International
|
|
//----------------------------------------------------------------------------
|
|
#include <owl\owlpch.h>
|
|
#include <owl\applicat.h>
|
|
#include <owl\framewin.h>
|
|
#include <owl\dialog.h>
|
|
#include <owl\dc.h>
|
|
#include "aclock.h"
|
|
#include <alloc.h>
|
|
#include <dos.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <mmsystem.h>
|
|
#include <stdio.h>
|
|
|
|
#define USE_BWCC
|
|
|
|
#if defined(USE_BWCC)
|
|
#define IDD_ABOUT "IDD_ABOUT_BWCC"
|
|
#else
|
|
#define IDD_ABOUT "IDD_ABOUT"
|
|
#endif
|
|
|
|
const float Pi2 = 2*3.141592;
|
|
|
|
//
|
|
// Chime & cukoo sounds based on the WIN.INI entries
|
|
//
|
|
const char ChimeSoundStr[] = "SystemAsterisk";
|
|
const char CuckooSoundStr[] = "SystemExclamation";
|
|
|
|
//
|
|
// Animated class animates a set of bitmaps
|
|
//
|
|
class Animated {
|
|
public:
|
|
Animated(HINSTANCE hInst, int numB, char far* name, int delayTics, int endTics);
|
|
~Animated();
|
|
|
|
void DisplayBegin(TDC& dc, int x, int y);
|
|
void DisplayNext(TDC& dc);
|
|
|
|
BOOL IsRunning() {return WaitingTic;}
|
|
|
|
private:
|
|
int DelayTics; // Amount to delay between frames (18.2 ticks/sec)
|
|
int EndTics; // Amount to delay after sequence
|
|
int WaitingTic; // Countdown for animation timing
|
|
|
|
int NumBmps; // number of bitmaps
|
|
int CurBmp; // currently displayed bitmap
|
|
TBitmap** Bmps; // bitmaps
|
|
int X; // position of bitmap
|
|
int Y;
|
|
};
|
|
|
|
|
|
//
|
|
// Construct an animated sequence
|
|
//
|
|
Animated::Animated(HINSTANCE hInst, int numB, char far* name, int delayTics, int endTics)
|
|
: WaitingTic(0)
|
|
{
|
|
NumBmps = numB;
|
|
CurBmp = 0;
|
|
Bmps = new (TBitmap(*[NumBmps])); // create array of numB TBitmap*'s
|
|
|
|
DelayTics = delayTics;
|
|
EndTics = endTics;
|
|
|
|
// Load in bitmap resources
|
|
//
|
|
for (int j = 0; j < NumBmps; j++) {
|
|
char resName[40];
|
|
wsprintf(resName, "%s%d", name, j+1);
|
|
Bmps[j] = new TBitmap(hInst, resName);
|
|
}
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
Animated::~Animated()
|
|
{
|
|
for (int j = 0; j < NumBmps; j++)
|
|
delete Bmps[j];
|
|
delete Bmps;
|
|
}
|
|
|
|
//
|
|
// Begin to draw the series of bitmaps timed to the timer.
|
|
//
|
|
void
|
|
Animated::DisplayBegin(TDC& dc, int x, int y)
|
|
{
|
|
CurBmp = 0;
|
|
X = x;
|
|
Y = y;
|
|
WaitingTic = 1; // prime the time clock
|
|
DisplayNext(dc);
|
|
}
|
|
|
|
//
|
|
// Draw each of the bitmaps timed to the timer.
|
|
//
|
|
void
|
|
Animated::DisplayNext(TDC& dc)
|
|
{
|
|
WaitingTic--;
|
|
if (WaitingTic || CurBmp == NumBmps)
|
|
return;
|
|
|
|
TMemoryDC memDC(dc);
|
|
|
|
memDC.SelectObject(*Bmps[CurBmp]);
|
|
dc.BitBlt(X, Y, Bmps[CurBmp]->Width(), Bmps[CurBmp]->Height(),
|
|
memDC, 0, 0, SRCCOPY);
|
|
|
|
WaitingTic = (++CurBmp == NumBmps) ? EndTics : DelayTics;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
//
|
|
//
|
|
//
|
|
class TClockWindow : public TFrameWindow {
|
|
public:
|
|
TClockWindow(const char* title);
|
|
~TClockWindow();
|
|
|
|
protected:
|
|
void SetupWindow();
|
|
|
|
void PaintHands(TDC& dc, struct time time);
|
|
void Paint(TDC&, BOOL, TRect&);
|
|
|
|
void EvTimer(UINT);
|
|
void CmAbout();
|
|
void CmChime();
|
|
void CmCuckoo();
|
|
|
|
private:
|
|
TBitmap* FaceBitmap; // Clock face bitmap
|
|
TPoint Center; // Center of clock
|
|
int Radius; // Clock radius
|
|
struct time LastTime; // Last time drawn
|
|
TPen* HourPen; // Pen for clock hour hand
|
|
TPen* MinutePen; // Pen for clock minute hand
|
|
Animated* CuckooAnim; // Cuckoo sequence
|
|
|
|
DECLARE_RESPONSE_TABLE(TClockWindow);
|
|
};
|
|
|
|
DEFINE_RESPONSE_TABLE1(TClockWindow, TFrameWindow)
|
|
EV_WM_TIMER,
|
|
EV_COMMAND(CM_ABOUT, CmAbout),
|
|
EV_COMMAND(CM_EFFECTCHIME, CmChime),
|
|
EV_COMMAND(CM_EFFECTCUCKOO, CmCuckoo),
|
|
END_RESPONSE_TABLE;
|
|
|
|
//
|
|
// Load animation sequences and set size in the constructor
|
|
//
|
|
TClockWindow::TClockWindow(const char* title)
|
|
: TFrameWindow(0, title, 0),
|
|
TWindow(0, title)
|
|
{
|
|
// load face bitmap
|
|
//
|
|
FaceBitmap = new TBitmap(*GetModule(), "FACE_BMP");
|
|
|
|
// load cuckoo sequence & set frame& end delay time in 1/10 sec tics
|
|
//
|
|
CuckooAnim = new Animated(*GetModule(), 8, "CUCKOO", 9, 80);
|
|
|
|
// Set the window size to size of bitmap plus non-client area size
|
|
//
|
|
Attr.W = FaceBitmap->Width() + 2*GetSystemMetrics(SM_CXBORDER);
|
|
Attr.H = FaceBitmap->Height() + GetSystemMetrics(SM_CYBORDER) +
|
|
GetSystemMetrics(SM_CYCAPTION) +
|
|
GetSystemMetrics(SM_CYMENU);
|
|
Attr.Style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX);
|
|
|
|
Center.x = FaceBitmap->Width() / 2;
|
|
Center.y = FaceBitmap->Height() / 2;
|
|
Radius = 3*(Center.x < Center.y ? Center.x : Center.y) / 4;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
TClockWindow::~TClockWindow()
|
|
{
|
|
KillTimer(1); // Get rid of timer
|
|
delete MinutePen; // delete pens, bitmaps, animations
|
|
delete HourPen;
|
|
delete FaceBitmap;
|
|
delete CuckooAnim;
|
|
}
|
|
|
|
//
|
|
// Do any HWindow required setup tasks here, not in constructor
|
|
//
|
|
void
|
|
TClockWindow::SetupWindow()
|
|
{
|
|
TFrameWindow::SetupWindow();
|
|
|
|
// set the timer - get called every minute
|
|
//
|
|
if (!SetTimer(1, 60000U, 0)) {
|
|
MessageBox("Out of Timers", GetApplication()->GetName(),
|
|
MB_ICONEXCLAMATION|MB_OK);
|
|
}
|
|
|
|
// Create the pens for the clock hands
|
|
//
|
|
HourPen = new TPen(TColor(0, 255, 255), 4); // cyan
|
|
MinutePen = new TPen(TColor(255, 0, 255), 4); // purple
|
|
}
|
|
|
|
//
|
|
// Paint the clock background and then the hands
|
|
//
|
|
void
|
|
TClockWindow::Paint(TDC& dc, BOOL, TRect&)
|
|
{
|
|
TMemoryDC memDC(dc);
|
|
memDC.SelectObject(*FaceBitmap);
|
|
dc.BitBlt(0, 0, FaceBitmap->Width(), FaceBitmap->Height(), memDC, 0, 0, SRCCOPY);
|
|
gettime(&LastTime); //paint the first time
|
|
PaintHands(dc, LastTime);
|
|
}
|
|
|
|
//
|
|
// Paint the hour and minute hands onto the face
|
|
//
|
|
void
|
|
TClockWindow::PaintHands(TDC& dc, struct time time)
|
|
{
|
|
// Compute the location of the hands
|
|
//
|
|
float minuteAngle = time.ti_min * Pi2 / 60;
|
|
float hourAngle = (time.ti_hour % 12) * Pi2 / 12 + minuteAngle/12;
|
|
|
|
TPoint hourPt((Radius/2)*sin(hourAngle) + Center.x,
|
|
(-Radius/2)*cos(hourAngle) + Center.y);
|
|
TPoint minutePt(Radius*sin(minuteAngle) + Center.x,
|
|
-Radius*cos(minuteAngle) + Center.y);
|
|
|
|
// Now draw them. Note the use of XOR to simplify erasing.
|
|
//
|
|
dc.SetROP2(R2_XORPEN);
|
|
dc.SelectObject(*HourPen);
|
|
dc.MoveTo(Center);
|
|
dc.LineTo(hourPt);
|
|
dc.SelectObject(*MinutePen);
|
|
dc.MoveTo(Center);
|
|
dc.LineTo(minutePt);
|
|
dc.RestorePen();
|
|
}
|
|
|
|
//
|
|
// Menu item Effect:Chime
|
|
//
|
|
// Stop any currently playing sound, and then play the chime sound.
|
|
//
|
|
void
|
|
TClockWindow::CmChime()
|
|
{
|
|
sndPlaySound(0,0);
|
|
sndPlaySound(ChimeSoundStr, SND_ASYNC);
|
|
}
|
|
|
|
//
|
|
// Menu item Effect:Cuckoo
|
|
//
|
|
// Stop any currently playing sound, and then play the cuckoo sound.
|
|
//
|
|
void
|
|
TClockWindow::CmCuckoo()
|
|
{
|
|
sndPlaySound(0,0);
|
|
sndPlaySound(CuckooSoundStr, SND_ASYNC);
|
|
|
|
// do cute graphics, temporarally speeding up timer for animation
|
|
//
|
|
TClientDC dc(*this);
|
|
SetTimer(1, 10, 0);
|
|
CuckooAnim->DisplayBegin(dc, 55, 125);
|
|
}
|
|
|
|
//
|
|
// Called each timer tick. Every 1/10th second during animation and
|
|
// every minute to paints hands
|
|
//
|
|
void
|
|
TClockWindow::EvTimer(UINT)
|
|
{
|
|
TClientDC dc(*this);
|
|
|
|
// If an animation is running, let it draw. If its done then, clean up.
|
|
//
|
|
if (CuckooAnim->IsRunning()) {
|
|
CuckooAnim->DisplayNext(dc);
|
|
if (!CuckooAnim->IsRunning()) {
|
|
SetTimer(1, 60000U, 0);
|
|
Invalidate(FALSE);
|
|
}
|
|
return;
|
|
}
|
|
|
|
PaintHands(dc, LastTime);
|
|
gettime(&LastTime);
|
|
PaintHands(dc, LastTime);
|
|
|
|
// Every hour play a chime
|
|
//
|
|
if (LastTime.ti_min == 0) {
|
|
CmChime();
|
|
if (LastTime.ti_hour == 0) // If midnight, time for the cuckoo
|
|
CmCuckoo();
|
|
}
|
|
}
|
|
|
|
// About dialog box
|
|
//
|
|
void
|
|
TClockWindow::CmAbout()
|
|
{
|
|
TDialog(this, IDD_ABOUT).Execute();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
class TClockApp : public TApplication {
|
|
public:
|
|
TClockApp() : TApplication() {}
|
|
void InitMainWindow();
|
|
};
|
|
|
|
void
|
|
TClockApp::InitMainWindow()
|
|
{
|
|
MainWindow = new TClockWindow("Cuckoo Clock");
|
|
MainWindow->AssignMenu("TOOL_MENU");
|
|
MainWindow->SetIcon(this, "ICON_1");
|
|
#if defined(USE_BWCC)
|
|
EnableBWCC();
|
|
#endif
|
|
}
|
|
|
|
int
|
|
OwlMain(int /*argc*/, char* /*argv*/ [])
|
|
{
|
|
return TClockApp().Run();
|
|
}
|