//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "DisplayThread.h"
#include "OSCABoard.h"
#include "OSCAVideo.h"
#include "FormDebug.h"
#include "FormMain.h"

#pragma package(smart_init)

// Helper macro for use when testing ;)
#define RANDOMCOLOR Color32(Random(255), Random(255), Random(255), 0xff)

//---------------------------------------------------------------------------

//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(&UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall VideoThread::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------

__fastcall VideoThread::VideoThread(TOSCABoard *owner)
	: TThread(true), m_pOwner(owner)
{
	if (this->m_pDisplayImage == NULL)
	{
		this->m_pDisplayImage = new TBitmap32();
	}

	this->m_pDisplayImage->SetSize(400, 240);
	this->m_pDisplayImage->Clear(clBlack32);
	this->m_pDisplayImage->ResamplerClassName = "TDraftResampler";
	this->fSrcRect = MakeRect(0, 0, 400, 240);
	this->fDstRect = MakeRect(0, 0, 600, 408);
}

__fastcall VideoThread::~VideoThread()
{
	if (this->m_pDisplayImage)
	{
		delete this->m_pDisplayImage;
		this->m_pDisplayImage = NULL;
	}
}

//---------------------------------------------------------------------------
void VideoThread::SetName()
{
	THREADNAME_INFO info;
	info.dwType = 0x1000;
	info.szName = "DisplayThread";
	info.dwThreadID = -1;
	info.dwFlags = 0;

	__try
	{
		RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD),(DWORD*)&info );
	}
	__except (EXCEPTION_CONTINUE_EXECUTION)
	{
	}
}

void __fastcall VideoThread::RunVideo(void)
{
	if (m_pOwner)
	{
		frames++;

		TOSCAVideo *m_pVideo = m_pOwner->GetVideoModule();
		if (m_pVideo)
		{
			this->m_pDisplayImage->BeginUpdate();
			this->m_pDisplayImage->Lock();

			for (int i = 16; i < 256; i++)
			{
				for (int j = 96; j < 496; j++)
				{
					if (m_pVideo->fSpritesEnabled)
					{
						if (m_pVideo->fSpriteLine[i][j] > 0)
						{
							this->m_pDisplayImage->Pixel[j - 96][i - 16] =
								m_pVideo->fDrawPalette[i - 16][m_pVideo->fSpriteLine[i][j] & 0xff];
						}
						else
						{
							this->m_pDisplayImage->Pixel[j - 96][i - 16] =
								m_pVideo->fDrawPalette[i - 16][m_pVideo->fVideoLine[i][j]];
						}
					}
					else
					{
						this->m_pDisplayImage->Pixel[j - 96][i - 16] =
							m_pVideo->fDrawPalette[i - 16][m_pVideo->fVideoLine[i][j]];
					}
				}
			}

			this->m_pDisplayImage->Unlock();
			this->m_pDisplayImage->EndUpdate();

			if ((MainForm) && (MainForm->Screen) && (MainForm->Screen->Buffer))
			{
				// Render to display
				MainForm->Screen->Buffer->BeginUpdate();
				MainForm->Screen->Buffer->Draw(fDstRect, fSrcRect, this->m_pDisplayImage);
				MainForm->Screen->Buffer->EndUpdate();
				MainForm->Screen->Refresh();
			}
		}
	}
}

//---------------------------------------------------------------------------
void __fastcall VideoThread::Execute()
{
	SetName();

	//---- Place thread code here ----
	lastScanline = -1;
	Sleep(20);
	while (!Terminated)
	{
		DWORD lastTicks = ::GetTickCount();
		//Synchronize(&this->RunVideo);
		RunVideo();
		DWORD elapsed = ::GetTickCount() - lastTicks;

		if (elapsed < 7)
		{
			Sleep(7 - elapsed);
		}
		//else
//			Sleep(1);
	}
}
//---------------------------------------------------------------------------
