Files
TeslaRel410/CODE/RP/MUNGA_L4/L4PLASMA.CPP
T
CydandClaude Fable 5 fdd9ac9d97 Initial import: Tesla Release 4.10 (Tesla:BattleTech & Tesla:Red Planet)
Archival snapshot of the Virtual World Entertainment Tesla cockpit
software, 1994-1996: MUNGA engine and L4 pod layer source (Borland
C++ 5.0), BT/RP game code, and game content (models, audio, maps,
gauges, Division renderer data). Includes third-party libraries:
Division dVS/DPL graphics, HMI SOS audio, WATTCP networking.

Files are preserved byte-for-byte (.gitattributes disables all
line-ending conversion). README.md documents the layout, target
hardware, and toolchain.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 13:21:58 -05:00

334 lines
8.1 KiB
C++

//===========================================================================//
// File: L4plasma.cpp //
// Project: MUNGA Brick: Applications-specific controls module //
// Contents: Interface specification for plasma display //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- -----------------------------------------------------------//
// 02/08/95 CPB Initial coding. //
// 06/15/95 CPB Changed to Video8BitBuffered, added transmission. //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. All rights reserved //
// PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include <mungal4.hpp>
#pragma hdrstop
#if !defined(L4PLASMA_HPP)
# include <l4plasma.hpp>
#endif
#if !defined(TIME_HPP)
# include <time.hpp>
#endif
//########################################################################
//############################# PlasmaDisplay ############################
//########################################################################
PlasmaDisplay::PlasmaDisplay(
Word port,
Word int_num
):
Video8BitBuffered(plasmaWidth, plasmaHeight)
{
//------------------------------------
// Create serial interface
//------------------------------------
pc_serial = new PCSerial(PCS_9600, PCS_N81, port, int_num);
if (pc_serial != NULL)
{
Register_Object(pc_serial);
pc_serial->FlowControlEnable(False);
//------------------------------------
// Turn off the cursor
//------------------------------------
static char
cursorOffString[] = { 27 /*ESC*/, 'G', (char) 0x00 };
pc_serial->SendString(cursorOffString, 3);
}
//------------------------------------
// Clear update flag array
//------------------------------------
currentTransferLine = 0;
updateInProgress = False;
for(int i=0; i<plasmaHeight; ++i)
{
updateFlag[i] = 0;
}
Check_Fpu();
}
PlasmaDisplay::~PlasmaDisplay()
{
if (pc_serial != NULL)
{
//---------------------------------------------------------------------
// Flush data to plasma display
//---------------------------------------------------------------------
WaitForUpdate();
// This odd sequence of allocation, setting, and adding is necessary:
// if you try to combine them, the compiler gets confused as to which
// method to invoke for 'Now()'.
Time
then;
then = Now();
then += 5.0;
while (Now() < then)
{
//---------------------------------------------------
// Drop out of loop when ALL data has been sent
//---------------------------------------------------
if (pc_serial->TransmitCharCount() <= 0)
{
if (!pc_serial->IsActive())
{
break;
}
}
}
//---------------------------------------------------------------------
// Delete the serial interface
//---------------------------------------------------------------------
Unregister_Object(pc_serial);
delete pc_serial;
}
Check_Fpu();
}
Logical
PlasmaDisplay::TestInstance() const
{
return Video8BitBuffered::TestInstance();
}
void
PlasmaDisplay::ShowInstance(char *indent)
{
cout << indent << "Plasma:\n";
char
temp[80];
Str_Copy(temp,indent, 80);
Str_Cat(temp,"...", 80);
Video8BitBuffered::ShowInstance(temp);
Check_Fpu();
}
void
sendLine(
PCSerial *pc_serial,
int line_number,
Byte *source_pointer,
int source_width
)
{
char
graphics[32]; // We only need 16...the extra is just in case.
int
x,
index;
Byte
byte,
byte_bit;
//--------------------------------------------
// Send header
//--------------------------------------------
graphics[0] = (char) 27; // ascii ESC
graphics[1] = 'P'; // graphics command
graphics[2] = (char) 0; // screen number
graphics[3] = (char) line_number; // Y position
graphics[4] = (char) 0; // X BYTE position
graphics[5] = (char) ((source_width+7)>>3); // width in bytes
graphics[6] = (char) 1;
pc_serial->SendString(graphics, 7);
//--------------------------------------------
// Send data
//--------------------------------------------
byte = 0;
byte_bit = 0x80;
index = 0;
for(x=0; x<source_width; ++x)
{
//
// Add bit to byte
//
if (*source_pointer++)
{
byte |= byte_bit;
}
//
// Update bit position
//
byte_bit >>= 1;
//
// If entire byte collected, send it
//
if (byte_bit == 0)
{
Verify(index < sizeof(graphics));
graphics[index++] = byte;
byte = 0;
byte_bit = 0x80;
}
}
//
// End of source line: send remaining bits
//
if (byte_bit != 0x80)
{
graphics[index++] = byte;
}
//
// Send graphics data
//
pc_serial->SendString(graphics, index);
Check_Fpu();
}
void
PlasmaDisplay::Scan(Logical forceAll)
{
Word
changed_line = (Word) forceAll,
*changed_line_pointer = changedLine;
char
*update_pointer=updateFlag;
int
y;
for(y=0; y<plasmaHeight; ++y,++update_pointer)
{
//---------------------------------------------------------
// Scan for changed lines
//---------------------------------------------------------
changed_line += *changed_line_pointer;
*changed_line_pointer++ = 0;
if (changed_line)
{
*update_pointer = 1;
updateInProgress = True;
}
}
Check_Fpu();
}
Logical
PlasmaDisplay::Update(Logical force_all)
{
int
transfer_count,
total_count;
Logical
result = True; // True == 'more to send, not done'
if (pc_serial != NULL)
{
//-----------------------------------------
// Accumulate changed lines
//-----------------------------------------
forceAll |= force_all;
if (currentTransferLine == 0)
{
Scan(forceAll);
forceAll = False;
}
//-----------------------------------------
// Send only if the buffer is empty
//-----------------------------------------
if (pc_serial->TransmitCharCount() == 0)
{
total_count = plasmaHeight;
transfer_count = 4;
while(transfer_count>0)
{
//-----------------------------------------
// Transfer a line if it's ready
//-----------------------------------------
if (updateFlag[currentTransferLine])
{
//-----------------------------------------
// Decrement the 'transfer count'
//-----------------------------------------
--transfer_count;
//-----------------------------------------
// Clear the 'update' flag
//-----------------------------------------
updateFlag[currentTransferLine] = 0;
//-----------------------------------------
// Send the line data to the display
//-----------------------------------------
sendLine(
pc_serial,
currentTransferLine,
pixelBuffer->Data.MapPointer +
(pixelBuffer->Data.Size.x * currentTransferLine),
pixelBuffer->Data.Size.x
);
}
//-----------------------------------------
// Increment currentTransferLine
//-----------------------------------------
if (++currentTransferLine >= plasmaHeight)
{
currentTransferLine = 0;
}
//-----------------------------------------
// Reset to top if all lines scanned
//-----------------------------------------
if (--total_count < 0)
{
currentTransferLine = 0; // reset to top line
updateInProgress = False;
result = False; // False == 'all data sent'
break;
}
}
}
}
Check_Fpu();
return result;
}
void
PlasmaDisplay::WaitForUpdate()
{
Time
end_time;
end_time = Now();
end_time += 5.0; // We'll wait this many seconds to update the display-
while (updateInProgress)
{
Update(False);
if (Now() >= end_time)
{
break;
}
}
Check_Fpu();
}