예제 #1
0
//////////////////////////////////////////////////////////////////////////////
///
///	Get the operation
///
//////////////////////////////////////////////////////////////////////////////
Operation controller::getOperation(unsigned char* ptr) {
 unsigned char operation = ptr[getOperationPosition(ptr)];

 if (operation == '+') {
  if (GetVerbose())
   SpacePrint("Addition detected!\n");

  return ADD;
 }

 if (operation == '-') {
  if (GetVerbose())
   SpacePrint("Subtraction detected!\n");

  return SUBTRACTION;
 }

 if ((operation == '*') || (operation == 'x') || (operation == 'X')) {
  if (GetVerbose())
   SpacePrint("Multiplication detected!\n");

  return MULTIPLY;
 }

 if (operation == 'z') {
  if (GetVerbose())
   SpacePrint("Multiplication Matrix detected!\n");
  return MATRIXMUL;
 }
 if (GetVerbose())
  SpacePrint("Division detected!\n");

 return DIVIDE;
}
예제 #2
0
//////////////////////////////////////////////////////////////////////////////
///
///	Send result to output
///
//////////////////////////////////////////////////////////////////////////////
void controller::sendResult(long data)
{
 if (GetVerbose())
  SpacePrint("Result:%d\n", data);

 int i;
 unsigned long power;
 unsigned int digit;

 // Negative number
 if (data < 0)
 {
  sendCharacter('-');
  data *= -1;
 }

 for(i=getOrder(data);i>=0;i--)
 {
  power = pow(10, i);
  digit = data/power;
  data -= digit*power;
  sendCharacter(itoa(digit));
 }

 sendCharacter(0xD);
}
예제 #3
0
void EXTR::launch_face_detection(void) {
	if (GetVerbose())
		SpacePrint("EXTR: Launching Face Detection\n");
	
	if (++m_currentBitmapImage > MAX_NB_IMAGE)
		m_currentBitmapImage = 1;
	
	JMSG messageToFace;
	messageToFace.command = SCMD_BEGIN_FACE_DETECTION;
	messageToFace.param0 = m_decompressedImageAddr[m_currentBitmapImage-1];
	messageToFace.param1 = m_currentJPEGImageNo;
	computeFor(1);

	ModuleWrite(FACEDETECT_ID, SPACE_BLOCKING, &messageToFace);

	if (GetVerbose())
		SpacePrint("EXTR: Returned from launch face detection for image #%d\n", m_currentBitmapImage);
}
예제 #4
0
//////////////////////////////////////////////////////////////////////////////
///
///	Get the first operand
///
//////////////////////////////////////////////////////////////////////////////
long controller::getFirstOperand(unsigned char* ptr) {
 unsigned char length = getOperationPosition(ptr);
 unsigned char* trimPtr = trimSpaces(ptr, &length);
 long number = convertCharacterToNumber(trimPtr, length);

 if (GetVerbose())
  SpacePrint("First operand:%d\n", number);

 return number;
}
예제 #5
0
파일: log.cpp 프로젝트: madnessw/thesnow
void wxLog::DoLog(wxLogLevel level, const wxChar *szString, time_t t)
{
    switch ( level ) {
        case wxLOG_FatalError:
            DoLogString(wxString(_("Fatal error: ")) + szString, t);
            DoLogString(_("Program aborted."), t);
            Flush();
#ifdef __WXWINCE__
            ExitThread(3);
#else
            abort();
#endif
            break;

        case wxLOG_Error:
            DoLogString(wxString(_("Error: ")) + szString, t);
            break;

        case wxLOG_Warning:
            DoLogString(wxString(_("Warning: ")) + szString, t);
            break;

        case wxLOG_Info:
            if ( GetVerbose() )
        case wxLOG_Message:
        case wxLOG_Status:
        default:    // log unknown log levels too
                DoLogString(szString, t);
            break;

        case wxLOG_Trace:
        case wxLOG_Debug:
#ifdef __WXDEBUG__
            {
                wxString msg = level == wxLOG_Trace ? wxT("Trace: ")
                                                    : wxT("Debug: ");
                msg << szString;
                DoLogString(msg, t);
            }
#endif // Debug
            break;
    }
}
예제 #6
0
// ----------------------------------------------------------------------------
//
void pxLogConsole::DoLogRecord(wxLogLevel level, const wxString &message, const wxLogRecordInfo &info)
{
	switch ( level )
	{
		case wxLOG_Trace:
		case wxLOG_Debug:
		{
			wxString str;
			TimeStamp( &str );
			MSW_OutputDebugString( str + message + L"\n" );
		}
		break;

		case wxLOG_FatalError:
			// This one is unused by wx, and unused by PCSX2 (we prefer exceptions, thanks).
			pxFailDev( "Stop using FatalError and use assertions or exceptions instead." );
		break;

		case wxLOG_Status:
			// Also unsed by wx, and unused by PCSX2 also (we prefer direct API calls to our main window!)
			pxFailDev( "Stop using wxLogStatus just access the Pcsx2App functions directly instead." );
		break;

		case wxLOG_Info:
			if ( !GetVerbose() ) return;
			// fallthrough!

		case wxLOG_Message:
			Console.WriteLn( L"[wx] %s", WX_STR(message));
		break;

		case wxLOG_Error:
			Console.Error(L"[wx] %s", WX_STR(message));
		break;

		case wxLOG_Warning:
			Console.Warning(L"[wx] %s", WX_STR(message));
		break;
	}
}
예제 #7
0
//
//  EXTR::decode_interleaved_scan
//////////////////////////////////////////////////////////////////////////////
/// 
/// This is the loop that extracts the jpeg data
/// 
///
/// @return =>  UINT16  : SUCCESS (always)
///
/// @note   =>  
//////////////////////////////////////////////////////////////////////////////
UINT16 EXTR::decode_interleaved_scan() {
	UINT16 i, j, horizontal_mcus, vertical_mcus;
	space_uint2 k, number_of_image_components_in_frame;
	space_uint4 l, m, horizontal_sampling_factor, vertical_sampling_factor;

	JMSG msg;
	
	// use these shortcuts	
	horizontal_mcus = m_jpeg_decoder_structure.horizontal_mcus;
	vertical_mcus = m_jpeg_decoder_structure.vertical_mcus;
	number_of_image_components_in_frame = m_jpeg_decoder_structure.number_of_image_components_in_frame;

	//
	// The jpeg image is stored in minimal component units or mcu. Each unit represents
	// a luminance block (Y) or a chrominance block (C). Since this decoder only supports
	// files that are encoded in the YUV 4:2:0 format, MCUs are stored in groups of 6. 
	// The four first MCUs are luminance component. The two lasts are chrominance Cb and Cr
	// that are colour information for the 4 previous luminance blocks. 
	// This can be seen as follow:
	//
	//		 _____________
	//		|      |      |
	//		|  Y1  |  Y2  |
	//		|   ___|___   |  
	//		|  |   |   |  |
    //      |--|Cb | Cr|--|
    //      |  |___|___|  |
    //      |      |      |
	//		|  Y3  |  Y4  |
	//		|______|______|  
    //


	// we scan all the vertical & horizontal mcus
	for (i=1; i<=vertical_mcus; i++)
	//for (i=1; i<=vertical_mcus/2; i++)
	{
		for (j=1; j<=horizontal_mcus;j++)
		//for (j=1; j<=horizontal_mcus/4;j++)
		{		
			// every mcu is composed of 3 components Y, Cb and Cr
			for (k=0; k<number_of_image_components_in_frame; k ++)
			{
				vertical_sampling_factor = m_jpeg_decoder_structure.vertical_sampling_factor [k];
				horizontal_sampling_factor = m_jpeg_decoder_structure.horizontal_sampling_factor [k];

				computeFor(1);

				for (l=0; l<vertical_sampling_factor; l++)
				{
					for (m=0; m<horizontal_sampling_factor; m++)
					{
						
						// triggers a notification to huffman thread to start Huffman decoding
						m_currentHuffmanComponent = k;

						// send information to HUFF module
						msg.command = SCMD_HUFFMAN_MCU;
						msg.param0 = m_currentHuffmanComponent;
						msg.param1 = m_inputAdd;
						
						computeFor(1);

						// send over request to huffman module
						ModuleWrite(HUFF_ID, SPACE_BLOCKING, &msg);

						computeFor(1);

						ModuleRead(HUFF_ID, SPACE_BLOCKING, &msg);
						
						if (GetVerbose())
						{
							static int roulette = 1;
							switch (roulette)
							{
							case 1: //[
							case 5:
								SpacePrint("|\b");
								break;
							case 2:
							case 7:
								SpacePrint("/\b");
								break;
							case 3:
							case 6:
								SpacePrint("-\b");
								break;
							case 4:
							case 8:
								SpacePrint("\\\b");
								break;
							}

							if (++roulette > 8) roulette = 1;

						}

						if (GetVerbose())
							SpacePrint("EXTR: decode_interleave_scan returned i:%d j:%d k:%d l:%d m:%d\n", i, j, k, l, m);


						if (msg.command != SCMD_ACK)
						{
							SpacePrint("EXTRACTOR ERROR : decode_interleaved has received a FAIL %d from HUFFMAN module\n", msg.param0); //this->name(), msg.param0);
							sc_stop();
						}
						else

						{
							m_inputAdd = msg.param0;
							m_bufferValid = false;
						}

					}
				}
			}
		}
	}
		
	// (.)(.)
	//   <
	//  ____
	// \/  \/
	// when we get here, it's the end of the image!
	
	if (GetVerbose())
		SpacePrint("\n");

 	return SUCCESS;
}
예제 #8
0
//////////////////////////////////////////////////////////////////////////////
/// 
/// Transmission of New Image command to IQTZ - wait for acknowledgement before
/// continuing
///
//////////////////////////////////////////////////////////////////////////////
void EXTR::communicate_IJPEG(unsigned short command) {
	JMSG newimage_message;

	switch (command)
	{


	case SCMD_NEW_IMAGE:
		
		if (GetVerbose())
			SpacePrint("EXTR: Sending NEW_IMAGE command to IQTZ - waiting for ACK\n");

		newimage_message.command = SCMD_NEW_IMAGE;
		newimage_message.param1 = m_currentJPEGImageNo;		// current image number
		newimage_message.param0 = m_infoImageHeaderAdd;	// current image info header

		computeFor(1);

		// transmitting request for decompressing new jpeg image - 
		// paramete is address of jpeg iomage to decompress
		ModuleWrite(IQTZ_ID, SPACE_BLOCKING, &newimage_message);
		
		computeFor(1);

		// waiting for acknowledgement with a blocking read
		// parameter is address of decompressed-YUV data
		ModuleRead(IQTZ_ID, SPACE_BLOCKING, &newimage_message);

		computeFor(1);

		if (newimage_message.command == SCMD_NEW_IMAGE_ACK) // collect address of bitmap
		{
			m_decompressedImageAddr[m_currentJPEGImageNo-1] = newimage_message.param0;
            //m_decompressedImageAddr[m_currentJPEGImageNo-1][VALID] = FALSE; // image data not valid while decompressing
		}

		if (GetVerbose())
			SpacePrint("EXTR: Return of ACK from IQTZ imageno:%d; address:%d\n", newimage_message.param0, m_decompressedImageAddr[m_currentJPEGImageNo-1]);

		computeFor(1);
		break;	


	case SCMD_END_IMAGE:
		
		if (GetVerbose())
			SpacePrint("EXTR: END_IMAGE command to send to IQTZ\n");


		newimage_message.command = SCMD_END_IMAGE;
		newimage_message.param1 = m_currentJPEGImageNo;
	
		computeFor(1);

		// transmitting end of request decompressing jpeg image - 
		// this tells the IJPEG module it will receive no more data
		
		ModuleWrite(HUFF_ID, SPACE_BLOCKING, &newimage_message);

		computeFor(1);

		// waiting for acknowledgement with a blocking read
		// parameter is address of decompressed-YUV data
		
		ModuleRead(IQTZ_ID, SPACE_BLOCKING, &newimage_message);
		
		computeFor(1);
		
		if (GetVerbose())
			SpacePrint("EXTR: Return of ACK for END_IMAGE command sent\n");

		break;	
	}
}
예제 #9
0
void EXTR::thread_extract_jpeg() {
	UINT8 last_marker;
	UINT8 last_returned;
	
    bool end_of_jpeg;
    bool has_at_least_one_jpeg_succeeded;
	
	JMSG outmsg;
	JMSG inmsg;
	
	m_currentJPEGImageNo = 0;
	m_currentBitmapImage = 0;
	m_bufferValid  = false;

	// represents the distance between each jpeg image
	m_jpegDist	= JPEG_IMAGE_SPACER;
	
    has_at_least_one_jpeg_succeeded = false;

	// reset to 0 structures and data related to jpeg decompression
	initialize();

	while(1) {
       end_of_jpeg = false;

		//
		// selection of jpeg preloop - sets pointer on proper image 
		//
        m_currentJPEGImageNo++; 
		if (m_currentJPEGImageNo > MAX_NB_IMAGE)
        {
        	// either we stop when we finish processing the images...
        	launch_face_detection();
        	sc_stop();
			
			// ...or we loop forever (comment out the previous line)
			m_currentJPEGImageNo = 1; 
            if (has_at_least_one_jpeg_succeeded == false)
            {
               SpacePrint("........................................................\n");
               SpacePrint("JPEG DECODER : ALL IMAGES SET FOR DECOMPRESSION\n");
               SpacePrint("HAVE FAILED -- STOPPING\n");
               SpacePrint("........................................................\n");
                sc_stop();
            }
        }

		m_infoImageHeaderAdd = (m_currentJPEGImageNo-1) * m_jpegDist; 	
		m_inputAdd = m_infoImageHeaderAdd + INFO_IMAGE_HEADER;
		m_bufferValid = false;
		computeFor(1);

        if (GetVerbose())
        {
           SpacePrint("EXTR: ********************************************** \n");
           SpacePrint("EXTR: Decompressing JPEG IMAGE no %d\n", m_currentJPEGImageNo);
           SpacePrint("EXTR: Input Address: 0x%x\n", m_inputAdd);
           SpacePrint("EXTR: ********************************************** \n");
        }
        else
        {
           SpacePrint("***JPEG %d\n",m_currentJPEGImageNo);
        }

		//
		// decode jpeg!
		//
		while (!end_of_jpeg) 
		{
			
			//
			// JPEG information is stored in between MARKERS. Each marker tells about 
			// the upcoming information to be read from the data
			//
			// this section scans markers and execute appropriate code according
			// to last marker read
			
			last_marker = read_next_marker();
			computeFor(1);
			
			switch (last_marker)
			{
				
			//
			// START OF FRAME MARKER
			//
			case SOF0:
			case SOF1:
			case SOF2:

                has_at_least_one_jpeg_succeeded = true;
				m_jpeg_decoder_structure.sof = last_marker;

				last_returned = read_sof_marker ();
				if (last_returned != SUCCESS)
				{
					SpacePrint("----------------------------------------\n");
					SpacePrint("EXTRACTOR: JPEG SOF DECODING ERROR no %d - skipping JPEG\n", last_returned); //, this->name(), last_returned);
					initialize();
					end_of_jpeg = true;
				}
					// write image header into memory
					// WORD 1 is X width
					// WORD 2 is Y height
					DeviceWrite(JPEGRAM_ID, m_infoImageHeaderAdd, &m_jpeg_decoder_structure.number_of_samples_per_line);
					DeviceWrite(JPEGRAM_ID, m_infoImageHeaderAdd+0x4ul, &m_jpeg_decoder_structure.number_of_lines);

	                if (GetVerbose())
                    {
					   SpacePrint("EXTR: JPEG STARTING DECOMPRESSION OF IMAGE no%d\n", m_currentJPEGImageNo);
                       SpacePrint("EXTR: Image size: %dx%d\n",
                                      m_jpeg_decoder_structure.number_of_samples_per_line, 
                                      m_jpeg_decoder_structure.number_of_lines);
                    }
                    else
                    {
					   SpacePrint("EXTR:JPEG%d\n", m_currentJPEGImageNo);
                    }


                    communicate_IJPEG(SCMD_NEW_IMAGE);
				//}
				
				break;
				

			//
			// START OF HUFFMAN TABLE MARKER AT 0xffc0
			//	
			case DHT: 
				
				outmsg.command = SCMD_HUFFMAN_DHT;
				outmsg.param0 = m_inputAdd;

				if (GetVerbose())
					SpacePrint("EXTR: Huffman Table found; sending address to HUFF module\n");

				ModuleWrite(HUFF_ID, SPACE_BLOCKING, &outmsg);

				computeFor(1);

				// wait for acknowledgement
				ModuleRead(HUFF_ID, SPACE_BLOCKING, &inmsg);

				if (GetVerbose())
					SpacePrint("EXTR: Return from blocking read - waiting Huffman ACK\n");

				
				// ack received with update with memory pointer
				if (inmsg.command == SCMD_ACK)
				{
					m_inputAdd = inmsg.param0;
					m_bufferValid = false;
				}
				else
				{
					SpacePrint("----------------------------------------\n");
					SpacePrint("EXTRACTOR: JPEG DHT DECODING ERROR no %d - skipping JPEG\n", inmsg.param0); //this->name(), inmsg.param0);
					initialize();
					end_of_jpeg = true;
				}
				break;

			//
			// START OF SCAN MARKER (DATA) AT 0xffda
			//
			case SOS:
				skip_marker ();	
				// extract file information
				/*
				last_returned = read_sos_marker ();
				if (last_returned != SUCCESS)
				{
					SpacePrint("----------------------------------------\n");
					SpacePrint("EXTRACTOR: JPEG SOS DECODING ERROR no %d - skipping JPEG\n", last_returned); //this->name(), last_returned);
					initialize();
					end_of_jpeg = true;
				}
				*/
				
				// this flys through the MCU and keep tracks of the current type of 
				// block being processed - for HUffman_thread. This should be 
				// optimised since it is always 4Y+CB+CR- TODO

				if (GetVerbose())
					SpacePrint("EXTR: Start of Scan Marker found... interleaving scan decoding can start\n");

				decode_interleaved_scan ();

				if (GetVerbose())
				{
					SpacePrint("EXTR: End of Scan Marker... waiting for other modules to finish\n");
				}


				// This is the end of the file, we terminate
				
				communicate_IJPEG(SCMD_END_IMAGE);


				
				// reinitialize buffers for jpeg decompression
				initialize();
				
				// we get off this loop and prepare for next image
				end_of_jpeg = true;

                // we launch execution of face detection - 
                // which emulates somne filters to render
                // new images
                launch_face_detection();
				
				computeFor(1);

				break;
				
			//
			// START OF QUANTIZATION TABLE MARKER AT 0xffdb
			//
			case DQT: 		
				
				// ack received with update with memory pointer
				if (read_dqt_marker() != SUCCESS)
				{
					SpacePrint("----------------------------------------\n");
					SpacePrint("EXTRACTOR: IQTZ DQT DECODING ERROR no %d - skipping JPEG\n", inmsg.param0); //this->name(), inmsg.param0);
					initialize();
					end_of_jpeg = true;
				}
				break;
				
				
			//
			// START OF IMAGE && END OF IMAGE MARKERS
			//
			case SOI:

				if (GetVerbose())
                   SpacePrint("EXTR: START OF IMAGE marker detected - reading image\n");

				break;
				
			//
			// START OF DEFINE RESTORE INTERVAL TABLE MARKER AT 0xffdb
			//
			/*
			case DRI:
				last_returned = read_dri_marker (); // read info and skip
				if (last_returned != SUCCESS)
				{
					SpacePrint("----------------------------------------\n");
					SpacePrint("EXTRACTOR: JPEG DRI DECODING ERROR no %d - skipping JPEG\n", last_returned); //this->name(), last_returned);
					initialize();
					end_of_jpeg = true;
				}
				break;
			*/	
			//
			// END OF IMAGE MARKER - nothing to do
			//
			case MARKER_EOI: // END OF IMAGE MARKER
				break;
				
			//
			// MARKERS WE SKIP
			//
			case APP0:			case APP1:			case APP2:			case APP3:			case APP4:
			case APP5:			case APP6:			case APP7:			case APP8:			case APP9:
			case APP10:			case APP11:			case APP12:			case APP13:			case APP14:
			case APP15:			case COM:			case DRI:
				skip_marker ();				
				break;
				
			//
			// ALL OTHER MARKERS ARE UNSUPPORTED BY THIS APPLICATION
			//
			default: 
				SpacePrint("----------------------------------------\n");
				SpacePrint("EXTRACTOR: JPEG DECODING UNDEFINED MARKER %d - skipping JPEG\n", last_marker); //this->name(), last_marker);
				initialize();
				end_of_jpeg = true;

				break;
			} // switch case
		
		}// while end of jpeg
	
    } // while 1
	
	
	
}
예제 #10
0
void pxLogConsole::DoLog( wxLogLevel level, const wxChar *szString, time_t t )
{
	wxString message(szString);
#else
void pxLogConsole::DoLogRecord(wxLogLevel level, const wxString &message, const wxLogRecordInfo &info)
{
#endif
	switch ( level )
	{
		case wxLOG_Trace:
		case wxLOG_Debug:
		{
			wxString str;
			TimeStamp( &str );
			MSW_OutputDebugString( str + message + L"\n" );
		}
		break;

		case wxLOG_FatalError:
			// This one is unused by wx, and unused by PCSX2 (we prefer exceptions, thanks).
			pxFailDev( "Stop using FatalError and use assertions or exceptions instead." );
		break;

		case wxLOG_Status:
			// Also unsed by wx, and unused by PCSX2 also (we prefer direct API calls to our main window!)
			pxFailDev( "Stop using wxLogStatus just access the Pcsx2App functions directly instead." );
		break;

		case wxLOG_Info:
			if ( !GetVerbose() ) return;
			// fallthrough!

		case wxLOG_Message:
			Console.WriteLn( L"[wx] %s", WX_STR(message));
		break;

		case wxLOG_Error:
			Console.Error(L"[wx] %s", WX_STR(message));
		break;

		case wxLOG_Warning:
			Console.Warning(L"[wx] %s", WX_STR(message));
		break;
	}
}


// ----------------------------------------------------------------------------
void ConsoleTestThread::ExecuteTaskInThread()
{
	static int numtrack = 0;

	while( !m_done )
	{
		// Two lines, both formatted, and varied colors.  This makes for a fairly realistic
		// worst case scenario (without being entirely unrealistic).
		Console.WriteLn( L"This is a threaded logging test. Something bad could happen... %d", ++numtrack );
		Console.Warning( L"Testing high stress loads %s", L"(multi-color)" );
		Yield( 0 );
	}
}

// ----------------------------------------------------------------------------
// Pass an uninitialized file object. The function will ask the user for the
// filename and try to open it. It returns true on success (file was opened),
// false if file couldn't be opened/created and -1 if the file selection
// dialog was canceled.
//
static bool OpenLogFile(wxFile& file, wxString& filename, wxWindow *parent)
{
	filename = wxSaveFileSelector(L"log", L"txt", L"log.txt", parent);
	if ( !filename ) return false; // canceled

	if( wxFile::Exists(filename) )
	{
		bool bAppend = false;
		wxString strMsg;
		strMsg.Printf(L"Append log to file '%s' (choosing [No] will overwrite it)?",
						filename.c_str());

		switch ( Msgbox::ShowModal( _("Save log question"), strMsg, MsgButtons().YesNo().Cancel() ) )
		{
			case wxID_YES:
				bAppend = true;
			break;

			case wxID_NO:
				bAppend = false;
			break;

			case wxID_CANCEL:
				return false;

			default:
				pxFailDev( "invalid message box return value" );
		}

		return ( bAppend ) ?
			file.Open(filename, wxFile::write_append) :
			file.Create(filename, true /* overwrite */);
	}

	return file.Create(filename);
}
예제 #11
0
// log all kinds of messages
void wxLogGui::DoLogRecord(wxLogLevel level,
                           const wxString& msg,
                           const wxLogRecordInfo& info)
{
    switch ( level )
    {
    case wxLOG_Info:
        if ( GetVerbose() )
        case wxLOG_Message:
    {
        m_aMessages.Add(msg);
        m_aSeverity.Add(wxLOG_Message);
        m_aTimes.Add((long)info.timestamp);
        m_bHasMessages = true;
    }
    break;

    case wxLOG_Status:
#if wxUSE_STATUSBAR
    {
        wxFrame *pFrame = NULL;

        // check if the frame was passed to us explicitly
        wxUIntPtr ptr = 0;
        if ( info.GetNumValue(wxLOG_KEY_FRAME, &ptr) )
        {
            pFrame = static_cast<wxFrame *>(wxUIntToPtr(ptr));
        }

        // find the top window and set it's status text if it has any
        if ( pFrame == NULL ) {
            wxWindow *pWin = wxTheApp->GetTopWindow();
            if ( wxDynamicCast(pWin, wxFrame) ) {
                pFrame = (wxFrame *)pWin;
            }
        }

        if ( pFrame && pFrame->GetStatusBar() )
            pFrame->SetStatusText(msg);
    }
#endif // wxUSE_STATUSBAR
    break;

    case wxLOG_Error:
        if ( !m_bErrors ) {
#if !wxUSE_LOG_DIALOG
            // discard earlier informational messages if this is the 1st
            // error because they might not make sense any more and showing
            // them in a message box might be confusing
            m_aMessages.Empty();
            m_aSeverity.Empty();
            m_aTimes.Empty();
#endif // wxUSE_LOG_DIALOG
            m_bErrors = true;
        }
        wxFALLTHROUGH;

    case wxLOG_Warning:
        if ( !m_bErrors ) {
            // for the warning we don't discard the info messages
            m_bWarnings = true;
        }

        m_aMessages.Add(msg);
        m_aSeverity.Add((int)level);
        m_aTimes.Add((long)info.timestamp);
        m_bHasMessages = true;
        break;

    case wxLOG_Debug:
    case wxLOG_Trace:
        // let the base class deal with debug/trace messages
        wxLog::DoLogRecord(level, msg, info);
        break;

    case wxLOG_FatalError:
    case wxLOG_Max:
        // fatal errors are shown immediately and terminate the program so
        // we should never see them here
        wxFAIL_MSG("unexpected log level");
        break;

    case wxLOG_Progress:
    case wxLOG_User:
        // just ignore those: passing them to the base class would result
        // in asserts from DoLogText() because DoLogTextAtLevel() would
        // call it as it doesn't know how to handle these levels otherwise
        break;
    }
}