#ifndef VLAB_CONTROL_H
#define VLAB_CONTROL_H

/*
**  VLab hardware control stuff.
**  © 2002 Kakace Productions
**
*/

#include <exec/types.h>


/*------------------------------------------------------------------------------------------------*/

struct VLabInfos {
    UBYTE  *vi_VLabAddress;         /* Board's address */
    ULONG   vi_BoardType;           /* 0 = VLab Classic, 65538 = VLab Y/C */

    void    (*vi_fSkipLuma)(void *VLabAddress, ULONG frame, ULONG count);
    void    (*vi_fSkipChroma)(void *VLabAddress, ULONG frame, ULONG count);
    void    (*vi_fGrabLuma)(void *VLabAddress, UBYTE *output, ULONG output_spacing, ULONG width, ULONG height,
                            ULONG line_skip, ULONG flags);
    void    (*vi_fGrabChroma)(void *VLabAddress, UBYTE *output, ULONG output_spacing, ULONG width,
                            ULONG height, ULONG line_skip);

    ULONG   vi_XPos;                /* X position [0; 716]                           */
    ULONG   vi_YPos;                /* Y position [0; 516] (NTSC) or [0; 616] (PAL)  */
    ULONG   vi_Width;               /* Scan width [4; 720]                           */
    ULONG   vi_Height;              /* Scan height [4; 520] (NTSC) or [4; 620] (PAL) */

    UBYTE   *vi_YBuff;              /* Y buffer  : numPixels                     */
    UBYTE   *vi_UVBuff;             /* UV buffer : sizeof(YBuff) / RATIO_YUV * 2 */

    UBYTE   vi_Flags;               /* Various flags (see below) */
    UBYTE   vi_Video;               /* Video standard (VIDEO_#?) */
    UBYTE   vi_Hue;                 /* Hue correction (NTSC)     */
    UBYTE   vi_Pad;

    UWORD   vi_ImageWidth;          /* (current resolution) */
    UWORD   vi_ImageHeight;         /* (current video-mode) */
};

extern struct VLabInfos VLabPrivate;


/*
** sp_Flags definitions
*/

#define VLABF_VTR           1   /* 1 = VTR ON (Video Tape Recorder) */
#define VLABF_COLOR         4   /* 1 = Color image                  */
#define VLABF_LACE          8   /* 1 = Interlaced mode              */
#define VLABF_HIRES        16   /* 1 = HiRes mode                   */
#define VLABF_PREFILTER    32   /* 1 = Luminance pre-filter OFF     */
#define VLABF_BW_SOURCE    64   /* 1 = B&W source                   */


/*
** sp_Filters definitions
** Each definition matches the horizontal peaking register assignments (SAA9051)
*/

#define VLABF_BANDPASS_MASK     0x03
#define VLABF_BANDPASS_SHIFT    4
#define FILTER_BANDPASS_R(x)   ((x >> VLABF_BANDPASS_SHIFT) & VLABF_BANDPASS_MASK)
#define FILTER_BANDPASS_W(r,x) ((r & ~(VLABF_BANDPASS_MASK << VLABF_BANDPASS_SHIFT))|((x & VLABF_BANDPASS_MASK) << VLABF_BANDPASS_SHIFT))

#define VLABF_BANDPASS_41       0       /* 4.1 MHz */
#define VLABF_BANDPASS_38       1       /* 3.8 MHz */
#define VLABF_BANDPASS_26       2       /* 2.6 MHz */
#define VLABF_BANDPASS_29       3       /* 2.9 MHz */

#define VLABF_CORING_MASK       0x03
#define VLABF_CORING_SHIFT      2
#define FILTER_CORING_R(x)     ((x >> VLABF_CORING_SHIFT) & VLABF_CORING_MASK)
#define FILTER_CORING_W(r,x)   ((r & ~(VLABF_CORING_MASK << VLABF_CORING_SHIFT))|((x & VLABF_CORING_MASK) << VLABF_CORING_SHIFT))

#define VLABF_CORING_OFF        0
#define VLABF_CORING_4BITS      1
#define VLABF_CORING_5BITS      2
#define VLABF_CORING_6BITS      3

#define VLABF_FACTOR_MASK       0x03
#define FILTER_FACTOR_R(x)     (x & VLABF_FACTOR_MASK)
#define FILTER_FACTOR_W(r,x)   ((r & ~VLABF_FACTOR_MASK)|(x & VLABF_FACTOR_MASK))

#define VLABF_FACTOR_0          0       /* 0    */
#define VLABF_FACTOR_25         1       /* 0.25 */
#define VLABF_FACTOR_50         2       /* 0.50 */
#define VLABF_FACTOR_100        3       /* 1    */


/*
** Various constants. Some are fixed settings (hardware dependent).
*/

#define VLAB_MAXWIDTH       720
#define VLAB_MAXHEIGHT_PAL  620
#define VLAB_MAXHEIGHT_NTSC 520
#define VLAB_RATIO_YUV        4


#define VLAB_GAMMA_MIN      -30
#define VLAB_GAMMA_MAX       30
#define VLAB_BRIGHT_MIN     -40
#define VLAB_BRIGHT_MAX      40
#define VLAB_CONTRAST_MIN   -40
#define VLAB_CONTRAST_MAX    40


enum VLab_VideoStd {        /* ID   Chrom. trap  Colour carrier  #lines */
    VIDEO_PAL_B,            /*  0      4.43       4 433 618.75     625  */
    VIDEO_PAL_N,            /*  1      4.43       3 582 056.25     625  */

    VIDEO_525 = 2,          /*  2                                       */
    VIDEO_PAL_M,            /*  2      4.43       3 575 611.49     525  */
    VIDEO_NTSC_443,         /*  3      3.58       4 433 618.75     525  */
    VIDEO_NTSC_M            /*  4      3.58       3 579 545.00     525  */
};


/*------------------------------------------------------------------------------------------------*/
/*========================================== PROTOTYPES ==========================================*/
/*------------------------------------------------------------------------------------------------*/

ULONG VLab_IdentifyHardware(void);
int   VLab_OwnHardware(void);
void  VLab_FreeHardware(void);
int   VLab_AllocateYUV(void);
void  VLab_FreeYUV(void);

void VLab_ChangeInput(ULONG input);
void VLab_ChangeVideo(ULONG videoStd);
void VLab_ChangeHue(LONG hue);
void VLab_ChangeFlags(ULONG flags);
void VLab_ChangeFilters(ULONG filters);

ULONG VLab_FrameWidth(ULONG flags);
ULONG VLab_FrameHeight(ULONG video, ULONG flags);

void  VLab_LumaCorrection(LONG gamma, LONG brightness, LONG contrast);
BOOL  VLab_InitHardware(void);

const char *VLab_GetErrorString(ULONG err);

UBYTE VLab_WriteRegisters(void *VLabAddress, UBYTE *stream, ULONG length);
UBYTE VLab_ReadStatus(void *VLabAddress);

ULONG VLab_Grab(ULONG xpos, ULONG ypos, ULONG width, ULONG height, ULONG mode, BOOL color);
UBYTE *VLab_GetYBuffer(void);

/*
** VLab Classic specific functions.
*/
void VLab_SkipLuma(void *VLabAddress, ULONG frame, ULONG count);
void VLab_SkipChroma(void *VLabAddress, ULONG frame, ULONG count);
void VLab_GrabLuma(void *VLabAddress, UBYTE *output, ULONG output_spacing, ULONG width, ULONG height,
                    ULONG line_skip, ULONG flags);
void VLab_GrabChroma(void *VLabAddress, UBYTE *output, ULONG output_spacing, ULONG width,
                    ULONG height, ULONG line_skip);

/*
** VLab Y/C specific functions.
*/
void VLabYC_SkipLuma(void *VLabAddress, ULONG frame, ULONG count);
void VLabYC_SkipChroma(void *VLabAddress, ULONG frame, ULONG count);
void VLabYC_GrabLuma(void *VLabAddress, UBYTE *output, ULONG output_spacing, ULONG width, ULONG height,
                    ULONG line_skip, ULONG flags);
void VLabYC_GrabChroma(void *VLabAddress, UBYTE *output, ULONG output_spacing, ULONG width,
                    ULONG height, ULONG line_skip);

/*
** YUV to RGB conversion
*/
void VLab_YUV_to_RGB(UBYTE *buffer, ULONG numPix, ULONG mode);
void VLab_411_to_RGB(UBYTE *yBuff, UBYTE *uvBuff, UBYTE *buffer, ULONG numPix);
void VLab_211_to_RGB(UBYTE *yBuff, UBYTE *uvBuff, UBYTE *buffer, ULONG numPix);
void VLab_111_to_RGB(UBYTE *yBuff, UBYTE *uvBuff, UBYTE *buffer, ULONG numPix);

/*
** YUV to YUV422 conversion
*/
void VLab_YUV_to_Color(UBYTE *buffer, ULONG numPix, ULONG mode);
void VLab_YUV_to_Grey(UBYTE *buffer, ULONG numPix);
void VLab_211_to_422(UBYTE *yBuff, UBYTE *uvBuff, UBYTE *buffer, ULONG numPix);
void VLab_111_to_422(UBYTE *yBuff, UBYTE *uvBuff, UBYTE *buffer, ULONG numPix);
void VLab_Y_to_422(UBYTE *yBuff, UBYTE *buffer, ULONG numpix);


/*------------------------------------------------------------------------------------------------*/
/*
** VLab_Grab() error codes.
*/

#define VLABERR_OK          0           /* No error               */
#define VLABERR_BADPARAM    1           /* Bad parameter          */
#define VLABERR_I2C         2           /* Communication error    */
#define VLABERR_NOVIDEO     3           /* No video signal        */
#define VLABERR_SCANNING    4           /* Timeout while scanning */


/*
** VLab_Grab() mode definitions.
*/

#define CAPTURE_HIRES           0x00    /* HiRes 4:1:1      */
#define CAPTURE_LORES           0x01    /* LoRes 2:1:1      */
#define CAPTURE_THUMBNAIL       0x02    /* Thumbnail 1:1:1  */


/*------------------------------------------------------------------------------------------------*/

#endif  /* VLAB_CONTROL_H */

