- 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>
537 lines
16 KiB
ObjectPascal
537 lines
16 KiB
ObjectPascal
{$A+,B-,D+,F-,G+,I+,K+,L+,N+,P+,Q-,R-,S+,T-,V+,W-,X+,Y+}
|
|
{$M 25600,4096}
|
|
{ unit main.pas }
|
|
unit Main;
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
|
|
Forms, Dialogs, StdCtrls, DB, DBTables, DbiTypes, DbiProcs, DbiErrs,
|
|
ExtCtrls, Grids, DBGrids, TableEnh, ShowNew;
|
|
|
|
const
|
|
copiedTable = 'COPY.DB';
|
|
|
|
type
|
|
TMainForm = class(TForm)
|
|
Panel1: TPanel;
|
|
SharedBtn: TButton;
|
|
TblLockedBtn: TButton;
|
|
RecLockedBtn: TButton;
|
|
SysVersionBtn: TButton;
|
|
SysInfoBtn: TButton;
|
|
SysConfigBtn: TButton;
|
|
Label8: TLabel;
|
|
Panel2: TPanel;
|
|
Label9: TLabel;
|
|
DataSource1: TDataSource;
|
|
DBGrid1: TDBGrid;
|
|
FastInsertBtn: TButton;
|
|
Panel3: TPanel;
|
|
Label1: TLabel;
|
|
Label2: TLabel;
|
|
Label3: TLabel;
|
|
Label4: TLabel;
|
|
Label5: TLabel;
|
|
Label6: TLabel;
|
|
Label7: TLabel;
|
|
BlockInsertBtn: TButton;
|
|
CountLabel: TLabel;
|
|
PackTableBtn: TButton;
|
|
CopyTableBtn: TButton;
|
|
StatusLabel: TLabel;
|
|
TableEnhanced1: TTableEnhanced;
|
|
RemoveLocksBtn: TButton;
|
|
FastAppendBtn: TButton;
|
|
OpenDialog1: TOpenDialog;
|
|
procedure SharedBtnClick(Sender: TObject);
|
|
procedure TblLockedBtnClick(Sender: TObject);
|
|
procedure RecLockedBtnClick(Sender: TObject);
|
|
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
|
|
procedure SysVersionBtnClick(Sender: TObject);
|
|
procedure SysInfoBtnClick(Sender: TObject);
|
|
procedure SysConfigBtnClick(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure DataSource1DataChange(Sender: TObject; Field: TField);
|
|
procedure FastInsertBtnClick(Sender: TObject);
|
|
procedure PackTableBtnClick(Sender: TObject);
|
|
procedure CopyTableBtnClick(Sender: TObject);
|
|
procedure BlockInsertBtnClick(Sender: TObject);
|
|
procedure RemoveLocksBtnClick(Sender: TObject);
|
|
procedure FastAppendBtnClick(Sender: TObject);
|
|
private
|
|
{ Private declarations }
|
|
RecCount: Longint;
|
|
procedure ClearLabels;
|
|
procedure CreateTempTable;
|
|
procedure InsertRecords;
|
|
end;
|
|
|
|
var
|
|
MainForm: TMainForm;
|
|
|
|
implementation
|
|
|
|
{$R *.DFM}
|
|
|
|
{ METHOD: InsertRecords
|
|
PURPOSE: Inserts blocks of records specified by the BlockSize and
|
|
BlockTotal parameters of TTableEnhanced.
|
|
}
|
|
procedure TMainForm.InsertRecords;
|
|
var
|
|
W: Word;
|
|
MoveDone: Boolean;
|
|
|
|
begin
|
|
MoveDone := False;
|
|
{ Continue to call the WriteBlock method until it returns True }
|
|
with TableEnhanced1 do
|
|
begin
|
|
repeat
|
|
{ Allocate and Initialize the record buffer }
|
|
InitializeBuffer;
|
|
{ Fill the record buffer }
|
|
for W := 1 to BlockSize do
|
|
begin
|
|
Inc(RecCount);
|
|
InitIntegerField(FieldByName('IntField').Index, RecCount);
|
|
InitStringField(FieldByName('StrField').Index,
|
|
Format('Record %d', [RecCount]));
|
|
InitTimeField(FieldByName('TimeField').Index, SysUtils.Time);
|
|
{ After each record in the record buffer has been filled, move the
|
|
record buffer ponter to the next record in the record buffer }
|
|
NextRecord;
|
|
end;
|
|
{ Place the block of records into the table }
|
|
MoveDone := WriteBlock;
|
|
{ Check to see if all records have been placed into the table }
|
|
until MoveDone = True;
|
|
end
|
|
end;
|
|
|
|
{ METHOD: CreateTempTable
|
|
PURPOSE: Creates a table that is used for this exmaple.
|
|
}
|
|
procedure TMainForm.CreateTempTable;
|
|
begin
|
|
with TableEnhanced1 do
|
|
begin
|
|
TableName := 'TEMPTABL';
|
|
TableType := ttParadox;
|
|
FieldDefs.Clear;
|
|
IndexDefs.Clear;
|
|
try
|
|
FieldDefs.Add('IntField', ftInteger, 0, True);
|
|
FieldDefs.Add('StrField', ftString, 14, True);
|
|
FieldDefs.Add('TimeField', ftTime, 0, True);
|
|
IndexDefs.Add('', 'IntField', [ixPrimary]);
|
|
CreateTable;
|
|
except
|
|
on E:EDatabaseError do
|
|
begin
|
|
Screen.Cursor := crDefault;
|
|
if MessageDlg(E.Message + '. Would you like to create the table in ' +
|
|
' the executable''s directory?', mtConfirmation,
|
|
[mbYes, mbNo], 0) = mrYes then
|
|
begin
|
|
DatabaseName := '';
|
|
try
|
|
CreateTable;
|
|
except
|
|
on E:EDatabaseError do
|
|
begin
|
|
raise EEnhDBError.Create('Application is terminating');
|
|
Application.Terminate;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
raise EEnhDBError.Create('Application is terminating');
|
|
Application.Terminate;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ METHOD: ClearLabels
|
|
PURPOSE: Clears the IDAPI information labels.
|
|
}
|
|
procedure TMainForm.ClearLabels;
|
|
begin
|
|
Label1.Caption := '';
|
|
Label2.Caption := '';
|
|
Label3.Caption := '';
|
|
Label4.Caption := '';
|
|
Label5.Caption := '';
|
|
Label6.Caption := '';
|
|
Label7.Caption := '';
|
|
end;
|
|
|
|
{ METHOD: SharedBtnClick
|
|
PURPOSE: Check IDAPI to see if the currently opened table is shared.
|
|
}
|
|
procedure TMainForm.SharedBtnClick(Sender: TObject);
|
|
begin
|
|
ClearLabels;
|
|
if TableEnhanced1.IsTableShared = True then
|
|
Label1.Caption := 'Table is shared'
|
|
else
|
|
Label1.Caption := 'Table is NOT shared';
|
|
end;
|
|
|
|
{ METHOD: TblLockedBtnClick
|
|
PURPOSE: Check IDAPI to see if the currently opened table is locked.
|
|
}
|
|
procedure TMainForm.TblLockedBtnClick(Sender: TObject);
|
|
begin
|
|
ClearLabels;
|
|
Label1.Caption := Format('Table has %d table locks',
|
|
[TableEnhanced1.IsTableLocked(dbiWriteLock)]);
|
|
end;
|
|
|
|
{ METHOD: RecLockedBtnClick
|
|
PURPOSE: Check IDAPI to see if the current record is locked.
|
|
}
|
|
procedure TMainForm.RecLockedBtnClick(Sender: TObject);
|
|
begin
|
|
ClearLabels;
|
|
if TableEnhanced1.IsRecordLocked = True then
|
|
Label1.Caption := 'Current record is locked'
|
|
else
|
|
Label1.Caption := 'Current record is NOT locked';
|
|
end;
|
|
|
|
{ METHOD: SysVersionBtnClick
|
|
PURPOSE: Check IDAPI for system version information.
|
|
}
|
|
procedure TMainForm.SysVersionBtnClick(Sender: TObject);
|
|
var
|
|
Version: SysVersion;
|
|
|
|
begin
|
|
ClearLabels;
|
|
Version := TableEnhanced1.GetSysVersion;
|
|
with Version do
|
|
begin
|
|
Label1.Caption := Format('Engine version = %d', [iVersion]);
|
|
Label2.Caption := Format('Client interface level = %d', [iIntfLevel]);
|
|
Label3.Caption := 'Version date = ' + DateToStr(DateVer);
|
|
Label4.Caption := 'Version time = ' + TimeToStr(TimeVer);
|
|
end;
|
|
end;
|
|
|
|
{ METHOD: SysVersionBtnClick
|
|
PURPOSE: Check IDAPI for system information.
|
|
}
|
|
procedure TMainForm.SysInfoBtnClick(Sender: TObject);
|
|
var
|
|
Info: SysInfo;
|
|
|
|
begin
|
|
ClearLabels;
|
|
Info := TableEnhanced1.GetSysInfo;
|
|
with Info do
|
|
begin
|
|
Label1.Caption := Format('Buffer size in kb = %d', [iBufferSpace]);
|
|
Label2.Caption := Format('Heap size in kb = %d', [iHeapSpace]);
|
|
Label3.Caption := Format('# of loaded drivers = %d', [iDrivers]);
|
|
Label4.Caption := Format('# of active clients = %d', [iClients]);
|
|
Label5.Caption := Format('# of active sessions = %d', [iSessions]);
|
|
Label6.Caption := Format('# of open databases = %d', [iDatabases]);
|
|
Label7.Caption := Format('# of open cursors (all clients) = %d',
|
|
[iCursors]);
|
|
end;
|
|
end;
|
|
|
|
{ METHOD: SysVersionBtnClick
|
|
PURPOSE: Check IDAPI for system configuration information.
|
|
}
|
|
procedure TMainForm.SysConfigBtnClick(Sender: TObject);
|
|
var
|
|
Config: SysConfig;
|
|
begin
|
|
ClearLabels;
|
|
Config := TableEnhanced1.GetSysConfig;
|
|
with Config do
|
|
begin
|
|
if bLocalShare = True then
|
|
Label1.Caption := 'Table can be shared with non-idapi applications'
|
|
else
|
|
Label1.Caption := 'Table cannot be shared with non-idapi applications';
|
|
Label2.Caption := 'Network type = ' + szNetType;
|
|
Label3.Caption := 'Network user name = ' + szUserName;
|
|
Label4.Caption := 'Configuration file name = ' + szIniFile;
|
|
Label5.Caption := 'System language driver = ' + szLangDriver;
|
|
end;
|
|
end;
|
|
|
|
{ METHOD: FormCloseQuery
|
|
PURPOSE: Close and delete the temporary table when the applivcstion
|
|
is closed.
|
|
}
|
|
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
|
|
begin
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
if TableEnhanced1.Active = true then
|
|
begin
|
|
TableEnhanced1.Close;
|
|
TableEnhanced1.DeleteTable;
|
|
end;
|
|
except
|
|
on E:EDatabaseError do
|
|
MessageDlg(E.Message, mtError, [mbOk], 0);
|
|
end;
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
|
|
{ METHOD: FormCreate
|
|
PURPOSE: Create and open the temporary table.
|
|
}
|
|
procedure TMainForm.FormCreate(Sender: TObject);
|
|
begin
|
|
Screen.Cursor := crHourGlass;
|
|
{ Set the record counter to zero }
|
|
RecCount := 0;
|
|
Application.HintColor := clTeal;
|
|
ClearLabels;
|
|
try
|
|
{ Treate the temporary table }
|
|
CreateTempTable;
|
|
{ Open the table }
|
|
TableEnhanced1.Open;
|
|
{ Add initial records to the table }
|
|
InsertRecords;
|
|
{ Display the new records in the DBGrid }
|
|
TableEnhanced1.Refresh;
|
|
{ Set the cursor to the first record in the table }
|
|
TableEnhanced1.First;
|
|
except
|
|
on E:EDatabaseError do
|
|
begin
|
|
Screen.Cursor := crDefault;
|
|
MessageDlg(E.Message, mtError, [mbOk], 0);
|
|
Application.Terminate;
|
|
end;
|
|
end;
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
|
|
{ METHOD: DataSource1DataChange
|
|
PURPOSE: Update the record count whenever the data in the
|
|
table has changed.
|
|
}
|
|
procedure TMainForm.DataSource1DataChange(Sender: TObject; Field: TField);
|
|
begin
|
|
CountLabel.Caption := Format('Record count = %d',
|
|
[TableEnhanced1.RecordCount]);
|
|
end;
|
|
|
|
{ METHOD: FastInsertBtnClick
|
|
PURPOSE: Insert one record using the InsertFast Method.
|
|
}
|
|
procedure TMainForm.FastInsertBtnClick(Sender: TObject);
|
|
begin
|
|
Inc(RecCount);
|
|
{ Set the BlockSize to one so extra record buffers are not allocated.
|
|
NOTE: It would not effect the behavior of InsertFast to have BlockSize
|
|
greater than one; it would just be a waste of memory and
|
|
slightly slower. }
|
|
TableEnhanced1.BlockSize := 1;
|
|
try
|
|
with TableEnhanced1 do
|
|
begin
|
|
{ Allocate and Initialize the record buffer }
|
|
InitializeBuffer;
|
|
{ Fill the record buffer }
|
|
InitIntegerField(FieldByName('IntField').Index, RecCount);
|
|
InitStringField(FieldByName('StrField').Index, Format('Record %d',
|
|
[RecCount]));
|
|
InitTimeField(FieldByName('TimeField').Index, SysUtils.Time);
|
|
{ Insert the record }
|
|
InsertFast;
|
|
{ Make sure the Delphi controls are aware of the new record }
|
|
Refresh;
|
|
{ Move the cursor to the last record in the table }
|
|
Last;
|
|
StatusLabel.Caption := 'Status = Success';
|
|
end;
|
|
except
|
|
on E:EDatabaseError do
|
|
begin
|
|
Dec(RecCount);
|
|
MessageDlg(E.Message, mtError, [mbOk], 0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ METHOD: PackTableBtnClick
|
|
PURPOSE: Pack the currently opened table.
|
|
}
|
|
procedure TMainForm.PackTableBtnClick(Sender: TObject);
|
|
begin
|
|
Screen.Cursor := crHourGlass;
|
|
StatusLabel.Caption := 'Status = Packing...';
|
|
Application.ProcessMessages;
|
|
try
|
|
{ Pack table }
|
|
TableEnhanced1.Pack;
|
|
StatusLabel.Caption := 'Status = Success';
|
|
except
|
|
on E:EEnhDBError do
|
|
begin
|
|
Screen.Cursor := crDefault;
|
|
StatusLabel.Caption := 'Status = ERROR';
|
|
MessageDlg(E.Message, mtError, [mbOk], 0);
|
|
end;
|
|
end;
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
|
|
{ METHOD: CopyTableBtnClick
|
|
PURPOSE: Copy the currently opened table to another table of a
|
|
different name.
|
|
}
|
|
procedure TMainForm.CopyTableBtnClick(Sender: TObject);
|
|
begin
|
|
Screen.Cursor := crHourGlass;
|
|
StatusLabel.Caption := 'Status = Copying...';
|
|
Application.ProcessMessages;
|
|
try
|
|
{ Set the table name on the ViewNew form to "copiedTable" }
|
|
ViewNew.TableEnhanced1.DatabaseName :=
|
|
TableEnhanced1.DatabaseName;
|
|
ViewNew.TableEnhanced1.TableName := copiedTable;
|
|
{ Copy the table }
|
|
TableEnhanced1.CopyTable(copiedTable);
|
|
{ Open the table on the ViewNew form }
|
|
ViewNew.TableEnhanced1.Open;
|
|
Screen.Cursor := crDefault;
|
|
StatusLabel.Caption := 'Status = Success';
|
|
{ Display the ViewNew form thus showing the copied table }
|
|
ViewNew.ShowModal;
|
|
ViewNew.TableEnhanced1.Close;
|
|
{ If the user decided to delete the table, delete it }
|
|
if ViewNew.DeleteCopy.Checked = True then
|
|
ViewNew.TableEnhanced1.DeleteTable;
|
|
except
|
|
{ If the user decided to copy a table over a previously created
|
|
table, ask the user if the old table should be deleted.
|
|
NOTE: The table can always be overwritten if
|
|
TTableEnhanced.Overwrite is True. }
|
|
on EEnhDBFileExists do
|
|
begin
|
|
Screen.Cursor := crDefault;
|
|
StatusLabel.Caption := 'Status = Table Exists';
|
|
if MessageDlg('Table exists. Delete', mtConfirmation, [mbYes, mbNo], 0)
|
|
= mrYes then
|
|
begin
|
|
{ Delete the old table }
|
|
ViewNew.TableEnhanced1.DeleteTable;
|
|
StatusLabel.Caption := 'Status = Deleted';
|
|
end
|
|
else
|
|
StatusLabel.Caption := 'Status = Not deleted';
|
|
end;
|
|
on E:EDatabaseError do
|
|
begin
|
|
Screen.Cursor := crDefault;
|
|
StatusLabel.Caption := 'Status = ERROR';
|
|
MessageDlg(E.Message, mtError, [mbOk], 0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ METHOD: BlockInsertBtnClick
|
|
PURPOSE: Insert a block of records into the table.
|
|
}
|
|
procedure TMainForm.BlockInsertBtnClick(Sender: TObject);
|
|
begin
|
|
Screen.cursor := crHourGlass;
|
|
{ Set the BlockSize and BlockTotal. The following means: Insert a
|
|
total of 500 records, 100 records at a time. }
|
|
TableEnhanced1.BlockTotal := 500;
|
|
TableEnhanced1.BlockSize := 100;
|
|
StatusLabel.Caption := 'Status = Inserting...';
|
|
Application.ProcessMessages;
|
|
try
|
|
{ Insert the records }
|
|
InsertRecords;
|
|
{ Make sure the Delphi controls are aware of the new record }
|
|
TableEnhanced1.Refresh;
|
|
{ Move the cursor to the last record in the table }
|
|
TableEnhanced1.Last;
|
|
StatusLabel.Caption := 'Status = Success';
|
|
Screen.Cursor := crDefault;
|
|
except
|
|
on E:EDatabaseError do
|
|
begin
|
|
Screen.Cursor := crDefault;
|
|
StatusLabel.Caption := 'Status = ERROR';
|
|
MessageDlg(E.Message, mtError, [mbOk], 0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ METHOD: RemoveLocksBtnClick
|
|
PURPOSE: Remove all record locks on the table. NOTE: There are
|
|
record locks on records inserted with InsertFast. If no locks
|
|
are desired, set TTableEnhanced.InsertMode = "imNoLock". Also,
|
|
removing record locks before block or reocrd insertion increases
|
|
performance.
|
|
}
|
|
procedure TMainForm.RemoveLocksBtnClick(Sender: TObject);
|
|
begin
|
|
try
|
|
{ Release all record locks }
|
|
TableEnhanced1.ReleaseRecordLock(True);
|
|
except
|
|
on E:EDatabaseError do
|
|
begin
|
|
StatusLabel.Caption := 'Status = ERROR';
|
|
MessageDlg(E.Message, mtError, [mbOk], 0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TMainForm.FastAppendBtnClick(Sender: TObject);
|
|
begin
|
|
Inc(RecCount);
|
|
{ Set the BlockSize to one so extra record buffers are not allocated.
|
|
NOTE: It would not effect the behavior of AppendFast to have BlockSize
|
|
greater than one; it would just be a waste of memory and
|
|
slightly slower. }
|
|
TableEnhanced1.BlockSize := 1;
|
|
try
|
|
with TableEnhanced1 do
|
|
begin
|
|
{ Allocate and Initialize the record buffer }
|
|
InitializeBuffer;
|
|
{ Fill the record buffer }
|
|
InitIntegerField(FieldByName('IntField').Index, RecCount);
|
|
InitStringField(FieldByName('StrField').Index, Format('Record %d',
|
|
[RecCount]));
|
|
InitTimeField(FieldByName('TimeField').Index, SysUtils.Time);
|
|
{ Append the record }
|
|
AppendFast;
|
|
{ Make sure the Delphi controls are aware of the new record }
|
|
Refresh;
|
|
{ Move the cursor to the last record in the table }
|
|
Last;
|
|
StatusLabel.Caption := 'Status = Success';
|
|
end;
|
|
except
|
|
on E:EDatabaseError do
|
|
begin
|
|
Dec(RecCount);
|
|
MessageDlg(E.Message, mtError, [mbOk], 0);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end.
|