#include "mungal4.h" #pragma hdrstop #include "l4plasma.h" #include "..\munga\time.h" //######################################################################## //############################# PlasmaDisplay ############################ //######################################################################## PlasmaDisplay::PlasmaDisplay( //Win32 Serial Support: ADB 02/24/2007 //Word port, const char* port //Word int_num ): Video8BitBuffered(plasmaWidth, plasmaHeight), forceAll(False) { //------------------------------------ // Create serial interface //------------------------------------ //Win32 Serial Support: ADB 02/24/2007 //pc_serial = new PCSerial(PCS_9600, PCS_N81, port, int_num); pc_serial = new PCSerial(PCS_9600, PCS_N81, port); 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; iDrawFilledRectangle(0, 0xFF, GraphicsDisplay::Replace, 0, 0, this->width - 1, this->height - 1); this->Update(True); Check_Fpu(); } PlasmaDisplay::~PlasmaDisplay() { if (pc_serial != NULL) { //--------------------------------------------------------------------- // Flush data to plasma display //--------------------------------------------------------------------- this->DrawFilledRectangle(0, 0xFF, GraphicsDisplay::Replace, 0, 0, this->width - 1, this->height - 1); this->Update(True); 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.0f; while (Now() < then) { //--------------------------------------------------- // Drop out of loop when ALL data has been sent //--------------------------------------------------- if (pc_serial->CanDraw() <= 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) { std::cout << indent << "Plasma:\n"; char temp[80]; Str_Copy(temp,indent, 80); Str_Cat(temp,"...", 80); Video8BitBuffered::ShowInstance(temp); Check_Fpu(); } int sendLine( char *transfer_pointer, int line_number, Byte *source_pointer, int source_width ) { int x, index; Byte byte, byte_bit; //-------------------------------------------- // Send header //-------------------------------------------- transfer_pointer[0] = (char) 27; // ascii ESC transfer_pointer[1] = 'P'; // graphics command transfer_pointer[2] = (char) 0; // screen number transfer_pointer[3] = (char) line_number; // Y position transfer_pointer[4] = (char) 0; // X BYTE position transfer_pointer[5] = (char) ((source_width+7)>>3); // width in bytes transfer_pointer[6] = (char) 1; transfer_pointer += 7; //pc_serial->SendString(graphics, 7); //-------------------------------------------- // Send data //-------------------------------------------- byte = 0; byte_bit = 0x80; index = 0; for(x=0; x>= 1; // // If entire byte collected, send it // if (byte_bit == 0) { Verify(index < sizeof(graphics)); *transfer_pointer = byte; transfer_pointer++; index++; byte = 0; byte_bit = 0x80; } } // // End of source line: send remaining bits // if (byte_bit != 0x80) { transfer_pointer[index++] = byte; } // // Send graphics data // //pc_serial->SendString(graphics, index); Check_Fpu(); return index + 7; } void PlasmaDisplay::Scan(Logical forceAll) { Word changed_line = (Word) forceAll, *changed_line_pointer = changedLine; char *update_pointer=updateFlag; int y; for(y=0; yCanDraw()) { //----------------------------------------- // Accumulate changed lines //----------------------------------------- forceAll |= force_all; if (currentTransferLine == 0) { Scan(forceAll); forceAll = False; } //----------------------------------------- // Send only if the buffer is empty //----------------------------------------- total_count = plasmaHeight; transfer_count = 7; int transfer_length = 32 * transfer_count; char *transfer_data = new char[transfer_length]; char *transfer_pointer = transfer_data; int total_transfer_count = transfer_count; int total_transfer_length = 0; startWhile = Now(); int i = 0; while(transfer_count>0) { //----------------------------------------- // Transfer a line if it's ready //----------------------------------------- allStarts[i] = Now(); if (updateFlag[currentTransferLine]) { //----------------------------------------- // Decrement the 'transfer count' //----------------------------------------- --transfer_count; //----------------------------------------- // Clear the 'update' flag //----------------------------------------- updateFlag[currentTransferLine] = 0; //----------------------------------------- // Send the line data to the display //----------------------------------------- startSendLine = Now(); int length = sendLine(transfer_pointer, currentTransferLine, pixelBuffer->Data.MapPointer + (pixelBuffer->Data.Size.x * currentTransferLine), pixelBuffer->Data.Size.x ); endSendLine = Now(); transfer_pointer += length; total_transfer_length += length; } allEnds[i] = Now(); //----------------------------------------- // 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; } i++; } endWhile = Now(); dataSendStart = Now(); if (total_transfer_length > 0) { this->pc_serial->SendString(transfer_data, total_transfer_length); } dataSendEnd = Now(); __totalTransferLength = total_transfer_length; delete [] transfer_data; } Check_Fpu(); Time end = Now(); if (end.ticks - start.ticks > 100) { start = end; } return result; } void PlasmaDisplay::WaitForUpdate() { Time end_time; end_time = Now(); end_time += 5.0f; // We'll wait this many seconds to update the display- while (updateInProgress) { Update(False); if (Now() >= end_time) { break; } } Check_Fpu(); }