/* 
 *	Copyright (C) 2007 Gabest
 *	http://www.gabest.org
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */

#pragma once

#ifndef __AFXWIN_H__
	#error include 'stdafx.h' before including this file for PCH
#endif

class cdvdApp : public CWinApp
{
public:
	cdvdApp();

public:
	virtual BOOL InitInstance();

	DECLARE_MESSAGE_MAP()
};

//

struct cdvdSubQ
{
	BYTE ctrl:4;		// control and mode bits
	BYTE mode:4;		// control and mode bits
	BYTE trackNum;		// current track number (1 to 99)
	BYTE trackIndex;	// current index within track (0 to 99)
	BYTE trackM;		// current minute location on the disc (BCD encoded)
	BYTE trackS;		// current sector location on the disc (BCD encoded)
	BYTE trackF;		// current frame location on the disc (BCD encoded)
	BYTE pad;			// unused
	BYTE discM;			// current minute offset from first track (BCD encoded)
	BYTE discS;			// current sector offset from first track (BCD encoded)
	BYTE discF;			// current frame offset from first track (BCD encoded)
};

struct cdvdTD // NOT bcd coded
{
	UINT32 lsn;
	BYTE type;
};

struct cdvdTN
{
	BYTE strack;	// number of the first track (usually 1)
	BYTE etrack;	// number of the last track
};

// CDVDreadTrack mode values:

#define CDVD_MODE_2352	0	// full 2352 bytes
#define CDVD_MODE_2340	1	// skip sync (12) bytes
#define CDVD_MODE_2328	2	// skip sync+head+sub (24) bytes
#define CDVD_MODE_2048	3	// skip sync+head+sub (24) bytes
#define CDVD_MODE_2368	4	// full 2352 bytes + 16 subq

// CDVDgetDiskType returns:

#define CDVD_TYPE_ILLEGAL	0xff	// Illegal Disc
#define CDVD_TYPE_DVDV		0xfe	// DVD Video
#define CDVD_TYPE_CDDA		0xfd	// Audio CD
#define CDVD_TYPE_PS2DVD	0x14	// PS2 DVD
#define CDVD_TYPE_PS2CDDA	0x13	// PS2 CD (with audio)
#define CDVD_TYPE_PS2CD		0x12	// PS2 CD
#define CDVD_TYPE_PSCDDA 	0x11	// PS CD (with audio)
#define CDVD_TYPE_PSCD		0x10	// PS CD
#define CDVD_TYPE_UNKNOWN	0x05	// Unknown
#define CDVD_TYPE_DETCTDVDD	0x04	// Detecting Dvd Dual Sided
#define CDVD_TYPE_DETCTDVDS	0x03	// Detecting Dvd Single Sided
#define CDVD_TYPE_DETCTCD	0x02	// Detecting Cd
#define CDVD_TYPE_DETCT		0x01	// Detecting
#define CDVD_TYPE_NODISC 	0x00	// No Disc

// CDVDgetTrayStatus returns:

#define CDVD_TRAY_CLOSE		0x00
#define CDVD_TRAY_OPEN		0x01

// cdvdTD.type (track types for cds)

#define CDVD_AUDIO_TRACK	0x01
#define CDVD_MODE1_TRACK	0x41
#define CDVD_MODE2_TRACK	0x61

#define CDVD_AUDIO_MASK		0x00
#define CDVD_DATA_MASK		0x40
//	CDROM_DATA_TRACK	0x04	// do not enable this! (from linux kernel)

//

#define CACHE_BLOCK_COUNT 16

class CDVD
{
	HANDLE m_hFile;
	CString m_label;
	OVERLAPPED m_overlapped;
	struct {int count, size, offset;} m_block;
	struct {BYTE buff[2048 * CACHE_BLOCK_COUNT]; bool pending; int start, count;} m_cache;
	BYTE m_buff[2352];

	LARGE_INTEGER MakeOffset(int lsn);
	bool SyncRead(int lsn);

public:
	CDVD();
	virtual ~CDVD();

	bool Open(CString path);
	void Close();
	CString GetLabel();
	bool Read(int lsn, int mode = CDVD_MODE_2048);
	BYTE* GetBuffer();
	UINT32 GetTN(cdvdTN* buff);
	UINT32 GetTD(BYTE track, cdvdTD* buff);
};

