/*
 * video_out_acorn.c
 * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
 *
 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
 *
 * mpeg2dec 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 of the License, or
 * (at your option) any later version.
 *
 * mpeg2dec 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <stdlib.h>

#include "inttypes.h"

#include "video_out.h"
#include "video_out_internal.h"
#include "custom.h"
#include "yuv2rgb.h"

/*
typedef struct acorn_frame_s {
    vo_frame_t vo;
    uint8_t * rgb_ptr;
    int rgb_stride;
    int yuv_stride;
} acorn_frame_t;
 */
typedef struct acorn_instance_s {
    vo_instance_t vo;
    int prediction_index;
    vo_frame_t * frame_ptr[3];
    vo_frame_t frame[3];
    uint8_t * rgbdata;
    int rgbstride;
    int width;
    int height;
    int bpp;
} acorn_instance_t;

static void acorn_draw_frame (vo_frame_t * frame)
{
  register int i, width,width1, height, scrwidth;
  register char *dst, *src;

  acorn_instance_t * instance = (acorn_instance_t *) frame->instance;

  dst = (char *) paint_startaddr;
  src = (char *) frame->base[0];
  width = instance->width;
  if (width>DISP_WIDTH){
    src+=(width-DISP_WIDTH)>>1;
    width1=DISP_WIDTH;
  } else width1=width;
  height = instance->height;
  if (height>DISP_HEIGHT) {
    src+=((height-DISP_HEIGHT)>>1)*width;
    height=DISP_HEIGHT;
  }
  scrwidth = screen_bytesperrow;

  yuv2rgb((void *)dst, frame->base[0], //+((DISP_WIDTH-width1)>>1),
                       frame->base[2], //+((DISP_WIDTH-width1)>>2),
                       frame->base[1], //+((DISP_WIDTH-width1)>>2),
                       width1,
                       height,
                       scrwidth,
                       width,
                       width/2);

}

static int acorn_setup (vo_instance_t * instance, int width, int height)
{
    acorn_instance_t * _instance;
    _instance = (acorn_instance_t *) instance;

    _instance->width = width;
    _instance->height = height;
    InitAcornDisplay(width, height);

    yuv2rgb_init (DISP_BPP, MODE_RGB);

    return libvo_common_alloc_frames ((vo_instance_t *)_instance, width, height,
				      sizeof (vo_frame_t),
				      NULL, NULL, acorn_draw_frame);
}

void acorn_close(vo_instance_t * _instance)
{
  RestoreDesktop();
  libvo_common_free_frames (_instance);
}

vo_instance_t * vo_acorn_open (void)
{
    acorn_instance_t * instance;

    instance = malloc (sizeof (acorn_instance_t));
    if (instance == NULL)
	return NULL;

    instance->vo.setup = acorn_setup;
    instance->vo.close = acorn_close;
    instance->vo.get_frame = libvo_common_get_frame;
//    instance->framenum = -2;

    return (vo_instance_t *) instance;
}

/*
static void acorn_copy_slice (vo_frame_t * frame, uint8_t ** src)
{
}

static int acornslice_setup (vo_instance_t * instance, int width, int height)
{
    return libvo_common_alloc_frames (instance, width, height,
				      sizeof (acorn_frame_t),
				      acorn_copy_slice, NULL, acorn_draw_frame);
}

vo_instance_t * vo_acornslice_open (void)
{
    acorn_instance_t * instance;

    instance = malloc (sizeof (acorn_instance_t));
    if (instance == NULL)
	return NULL;

    instance->vo.setup = acornslice_setup;
    instance->vo.close = libvo_common_free_frames;
    instance->vo.get_frame = libvo_common_get_frame;

    return (vo_instance_t *) instance;
}

static vo_frame_t * rgb_get_frame (vo_instance_t * _instance, int flags)
{
    acorn_instance_t * instance;
    acorn_frame_t * frame;

    instance = (acorn_instance_t *) _instance;
    frame =
	(acorn_frame_t *) libvo_common_get_frame ((vo_instance_t *) instance,
						 flags);

    frame->rgb_ptr = instance->rgbdata;
    frame->rgb_stride = instance->rgbstride;
    frame->yuv_stride = instance->width;
    if ((flags & VO_TOP_FIELD) == 0)
        frame->rgb_ptr += frame->rgb_stride;
    if ((flags & VO_BOTH_FIELDS) != VO_BOTH_FIELDS) {
        frame->rgb_stride <<= 1;
        frame->yuv_stride <<= 1;
    }

    return (vo_frame_t *) frame;
}

static void rgb_copy_slice (vo_frame_t * _frame, uint8_t ** src)
{
    acorn_frame_t * frame;
    acorn_instance_t * instance;

    frame = (acorn_frame_t *) _frame;
    instance = (acorn_instance_t *) frame->vo.instance;

    yuv2rgb (frame->rgb_ptr, src[0], src[1], src[2], instance->width, 16,
	     frame->rgb_stride, frame->yuv_stride, frame->yuv_stride >> 1);
    frame->rgb_ptr += frame->rgb_stride << 4;
}

static void rgb_field (vo_frame_t * _frame, int flags)
{
    acorn_frame_t * frame;
    acorn_instance_t * instance;

    frame = (acorn_frame_t *) _frame;
    instance = (acorn_instance_t *) frame->vo.instance;

    frame->rgb_ptr = instance->rgbdata;
    if ((flags & VO_TOP_FIELD) == 0)
	frame->rgb_ptr += instance->rgbstride;
}

static int acornrgb_setup (vo_instance_t * _instance, int width, int height)
{
    acorn_instance_t * instance;

    instance = (acorn_instance_t *) _instance;

    instance->width = width;
    instance->rgbstride = width * instance->bpp / 8;
    instance->rgbdata = malloc (instance->rgbstride * height);

    yuv2rgb_init (instance->bpp, MODE_RGB);

    return libvo_common_alloc_frames ((vo_instance_t *) instance,
				      width, height, sizeof (acorn_frame_t),
				      rgb_copy_slice, rgb_field,
				      acorn_draw_frame);
}

vo_instance_t * vo_acornrgb16_open (void)
{
    acorn_instance_t * instance;

    instance = malloc (sizeof (acorn_instance_t));
    if (instance == NULL)
	return NULL;

    instance->vo.setup = acornrgb_setup;
    instance->vo.close = libvo_common_free_frames;
    instance->vo.get_frame = rgb_get_frame;
    instance->bpp = 16;

    return (vo_instance_t *) instance;
}

vo_instance_t * vo_acornrgb32_open (void)
{
    acorn_instance_t * instance;

    instance = malloc (sizeof (acorn_instance_t));
    if (instance == NULL)
	return NULL;

    instance->vo.setup = acornrgb_setup;
    instance->vo.close = libvo_common_free_frames;
    instance->vo.get_frame = rgb_get_frame;
    instance->bpp = 32;

    return (vo_instance_t *) instance;
}
 */
