Files
TeslaRel410/BORLAND/BC45/EXAMPLES/OWL/OWLAPPS/CALC/CALC.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

407 lines
8.2 KiB
C++

//----------------------------------------------------------------------------
// ObjectWindows - (C) Copyright 1991 by Borland International
// Simple four function calculator
//----------------------------------------------------------------------------
#include <owl\owlpch.h>
#include <owl\applicat.h>
#include <owl\dc.h>
#include <owl\dialog.h>
#include <owl\framewin.h>
#include <cstring.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define min(a,b) (((a) <(b)) ? (a) :(b))
const char AppName[] = "Calc"; // Name of app, window title & icon resource id
const int DisplayDigits = 15; // number of digits in calculator display
const int ID_DISPLAY = 400; // control ID of display static text
enum TCalcState {CS_FIRST, CS_VALID, CS_ERROR}; // calculator state
// Calculator dialog window object
//
class TCalc : public TDialog {
public:
TCalcState CalcStatus;
char Operator;
char Number[DisplayDigits + 1];
BOOL Negative;
double Operand;
TBrush BlueBrush;
TCalc();
void FlashButton(char key);
void Error();
void SetDisplay(double r);
void GetDisplay(double& r);
virtual void UpdateDisplay();
void CheckFirst();
void InsertKey(char key);
void CalcKey(char key);
void Clear();
protected:
//
// override EvCommand() defined by class TWindow
//
LRESULT EvCommand(UINT, HWND, UINT);
void EvPaint();
//
// message response functions
//
HBRUSH EvCtlColor(HDC, HWND hWndChild, UINT ctlType);
DECLARE_RESPONSE_TABLE(TCalc);
};
DEFINE_RESPONSE_TABLE1(TCalc, TDialog)
EV_WM_PAINT,
EV_WM_CTLCOLOR,
END_RESPONSE_TABLE;
//
// Calculator constructor. Create blue brush for calculator background,
// and do a clear command.
//
TCalc::TCalc()
: TWindow((TWindow*)0),
TDialog(0, AppName),
BlueBrush(TColor(0, 0, 255))
{
Clear();
}
//
// Colorize the calculator. Allows background to show through corners of
// buttons, uses yellow text on black background in the display, and sets
// the dialog background to blue.
//
HBRUSH
TCalc::EvCtlColor(HDC hDC, HWND hWndChild, UINT ctlType)
{
switch (ctlType) {
case CTLCOLOR_BTN:
SetBkMode(hDC, TRANSPARENT);
return (HBRUSH)GetStockObject(NULL_BRUSH);
case CTLCOLOR_STATIC:
SetTextColor(hDC, TColor::LtYellow);
SetBkMode(hDC, TRANSPARENT);
return (HBRUSH)GetStockObject(BLACK_BRUSH);
case CTLCOLOR_DLG:
SetBkMode(hDC, TRANSPARENT);
return (HBRUSH)BlueBrush;
default:
return TDialog::EvCtlColor(hDC, hWndChild, ctlType);
}
}
//
// Even dialogs can have their backgrounds painted on. This creates
// a red ellipse over the blue background.
//
void
TCalc::EvPaint()
{
TBrush redBrush(TColor(255, 0, 0));
TPaintDC dc(*this);
dc.SelectObject(redBrush);
dc.SelectStockObject(NULL_PEN);
TRect clientRect = GetClientRect();
clientRect.bottom = clientRect.right;
clientRect.Offset(-clientRect.right/4, -clientRect.right/4);
dc.Ellipse(clientRect);
}
//
// Flash a button with the value of Key. Looks exactly like a
// click of the button with the mouse.
//
void
TCalc::FlashButton(char key)
{
if (key == 0x0D)
key = '='; // Treat Enter like '='
HWND button = GetDlgItem(toupper(key));
if (button) {
::SendMessage(button, BM_SETSTATE, 1, 0);
for (int delay = 1; delay <= 30000; ++delay)
;
::SendMessage(button, BM_SETSTATE, 0, 0);
}
}
//
// here we handle all of the child id notifications (BN_CLICKED from the
// buttons) and all accelerators at once rather than have separate response
// table entries for each...
//
LRESULT
TCalc::EvCommand(UINT id, HWND hWndCtl, UINT notifyCode)
{
if (hWndCtl != 0 && notifyCode == BN_CLICKED)
CalcKey(char(id)); // button notification
else if (hWndCtl == 0 && notifyCode == 1) {
//
// from an accelerator
//
FlashButton(char(id));
CalcKey(char(id));
}
return TDialog::EvCommand(id, hWndCtl, notifyCode);
}
//
// Set Display text to the current value.
//
void
TCalc::UpdateDisplay()
{
char str[DisplayDigits + 2];
if (Negative)
strcpy(str, "-");
else
str[0] = '\0';
::SetWindowText(GetDlgItem(ID_DISPLAY), strcat(str, Number));
}
//
// Clear the calculator.
//
void
TCalc::Clear()
{
CalcStatus = CS_FIRST;
strcpy(Number, "0");
Negative = FALSE;
Operator = '=';
}
void
TCalc::Error()
{
CalcStatus = CS_ERROR;
strcpy(Number, "Error");
Negative = FALSE;
}
void
TCalc::SetDisplay(double r)
{
char* first;
char* last;
int charsToCopy;
char str[64];
//
// limit results of calculations to 7 digits to the right of the dec. point
//
r = (floor(r * 10000000L + .5)) / 10000000L;
sprintf(str, "%0.10f", r);
first = str;
Negative = FALSE;
if (str[0] == '-') {
first++;
Negative = TRUE;
}
if (strlen(first) > DisplayDigits + 1 + 10 )
Error();
else {
last = strchr(first, 0);
while (last[-1] == '0')
--last;
if (last[-1] == '.')
--last;
charsToCopy = min(DisplayDigits + 1, int(last - first));
strncpy(Number, first, charsToCopy);
Number[charsToCopy] = 0;
}
}
void
TCalc::GetDisplay(double& r)
{
r = atof(Number);
if (Negative)
r = -r;
}
void
TCalc::CheckFirst()
{
if (CalcStatus == CS_FIRST) {
CalcStatus = CS_VALID;
strcpy(Number, "0");
Negative = FALSE;
}
}
void
TCalc::InsertKey(char key)
{
int l = strlen(Number);
if (l < DisplayDigits) {
Number[l] = key;
Number[l + 1] = 0;
}
}
//
// Process calculator key.
//
void
TCalc::CalcKey(char key)
{
key = (char)toupper(key);
if (CalcStatus == CS_ERROR && key != 'C')
key = ' ';
if (key >= '0' && key <= '9') {
CheckFirst();
if (strcmp(Number, "0") == 0)
Number[0] = '\0';
InsertKey(key);
} else if (key == '+' || key == '-' || key == '*' ||
key == '/' || key == '=' || key == '%' || key == 0x0D) {
if (CalcStatus == CS_VALID) {
CalcStatus = CS_FIRST;
double r;
GetDisplay(r);
if (key == '%') {
switch(Operator) {
case '+':
case '-':
r = Operand * r / 100;
break;
case '*':
case '/':
r /= 100;
break;
}
}
switch(Operator) {
case '+':
SetDisplay(Operand + r);
break;
case '-':
SetDisplay(Operand - r);
break;
case '*':
SetDisplay(Operand * r);
break;
case '/':
if (r == 0)
Error();
else
SetDisplay(Operand / r);
break;
}
}
Operator = key;
GetDisplay(Operand);
} else
switch(key) {
case '.':
CheckFirst();
if (!strchr(Number, '.'))
InsertKey(key);
break;
case 0x8:
CheckFirst();
if (strlen(Number) == 1)
strcpy(Number, "0");
else
Number[strlen(Number) - 1] = '\0';
break;
case '_':
Negative = !Negative;
break;
case 'C':
Clear();
break;
}
UpdateDisplay();
}
//----------------------------------------------------------------------------
//
// Calculator application object
//
class TCalcApp : public TApplication {
public:
TCalcApp(const char far* name) : TApplication(name) {}
void InitMainWindow();
};
//
// Create calculator as the application's main window.
//
void
TCalcApp::InitMainWindow()
{
TWindow* calcWin = new TCalc;
calcWin->Attr.AccelTable = AppName;
MainWindow = new TFrameWindow(0, Name, calcWin, TRUE);
MainWindow->SetIcon(this, AppName);
MainWindow->Attr.Style &= ~(WS_MAXIMIZEBOX | WS_THICKFRAME);
}
int
OwlMain(int /*argc*/, char* /*argv*/ [])
{
return TCalcApp(AppName).Run();
}