// CMAMEScreen.cpp
// The main window
// Casey Fleser
// October 24, 1997

#include <BeHeaders>

#include "CMAMEScreen.h"
#include "CIOThread.h"
#include "CPalette.h"
#include "Defines.h"
#include "osdepend.h"

#pragma optimization_level 4

extern struct osd_bitmap *gBitmap;

CMAMEScreen::CMAMEScreen(
	int32		space,
	char			*name,
	status_t		*error) : BWindowScreen(name, space, error, false)
{
	mInitComplete = false;
	
	mDeltaX = mDeltaY = 0;
	mView = new BView(Bounds(), "MouseView", 0, 0);
	AddChild(mView);
	mIO = new CIOThread(this);
	mIO->Go();
	mPalette = new CPalette(this);
	mPalette->Go();
	
	switch (space) {
		case B_8_BIT_640x480:	mHeight = 480;	mWidth = 640;		break;
		case B_8_BIT_800x600:	mHeight = 600;	mWidth = 800;		break;
		case B_8_BIT_1024x768:	mHeight = 768;	mWidth = 1024;	break;
		case B_8_BIT_1280x1024:	mHeight = 1024;	mWidth = 1280;	break;
		case B_8_BIT_1600x1200:	mHeight = 1200;	mWidth = 1600;	break;
	}
}

CMAMEScreen::~CMAMEScreen()
{
//	delete mIO;		// killed in Quit()
//	delete mPalette;
}

void
CMAMEScreen::Quit()
{
	delete mIO;		// kill these here rather than destructor
	delete mPalette;

	Disconnect();

	BWindowScreen::Quit();
}

void
CMAMEScreen::ScreenConnected(
	bool		active)
{
	uint32	i;
	uchar	*buf;
	
	SetFrameBuffer(640, 480);
	MoveDisplayArea(0, 0);
	mBytesRow = CardInfo()->bytes_per_row;
	buf = mBase = (uchar*)CardInfo()->frame_buffer;
	
	for (i=0; i<480*640; i++)
		*buf++ = 0;
	
	set_mouse_position(320, 240);
	
	mInitComplete = true;
}

void
CMAMEScreen::ScreenChanged(
	BRect		screen_size,
	color_space	depth)
{
// This doesn't seem to work right, use guess from constructor
//	mHeight = screen_size.Height();
//	mWidth = screen_size.Width();
}

void
CMAMEScreen::MessageReceived(
	BMessage	 *inMessage)
{
	if (inMessage->what == eWhat_PollMouse) {
		uint32	button;
		BPoint	curPt;

		mView->GetMouse(&curPt, &button);
		set_mouse_position(320, 240);
		mDeltaX += curPt.x - 320;
		mDeltaY += curPt.y - 240;
	}
	else						
		BWindow::MessageReceived(inMessage);
}

void
CMAMEScreen::Init()
{
	Show();

	while (!mInitComplete)
		snooze(1000.0);
}

void
CMAMEScreen::Exit()
{
	PostMessage(B_QUIT_REQUESTED);
}

void
CMAMEScreen::InitPalette()
{
	mPalette->InitPalette();
}

void	
CMAMEScreen::SetPen(
	int16		inPen,
	uchar		inRed,
	uchar		inGreen,
	uchar		inBlue)
{
	mPalette->SetPen(inPen, inRed, inGreen, inBlue);
}

void
CMAMEScreen::GetPen(
	int16		inPen,
	uchar		*outRed,
	uchar		*outGreen,
	uchar		*outBlue)
{
	mPalette->GetPen(inPen, outRed, outGreen, outBlue);
}

void
CMAMEScreen::Resize(
	int16		inWidth,
	int16		inHeight)
{
}

void	
CMAMEScreen::CopyBits(
	void			*inSrc,
	int16		inHeight,
	int16		inWidth)
{
	uchar	*dstStart, *dst, *src = (uchar *)inSrc;
	int32	y, width;
	int32	ystart = (mHeight/2 - inHeight/2) & ~0x07;
	int32	yend = ystart + inHeight;
	int32	xstart = (mWidth/2 - inWidth/2)  & ~0x07;

	dstStart = mBase + xstart + (ystart * mBytesRow);
	
	for (y = ystart; y<yend; y++) {
		dstStart += mBytesRow;
		dst = dstStart;
		width = inWidth;
		while (width >= 4) {
			*(uint32 *)dst = *(uint32 *)src;
			dst += 4;
			src += 4;
			width -= 4;
		}
		while (width) {
			*dst++ = *src++;
			width--;
		}
	}
}

void
CMAMEScreen::PollMouse()
{
	PostMessage(eWhat_PollMouse);
}

void
CMAMEScreen::ReadMouse(
	int16		*outX,
	int16		*outY)
{
	*outX = mDeltaX;
	*outY = mDeltaY;
	
	mDeltaX = mDeltaY = 0;
}
