/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "Licence").
 * You may not use this file except in compliance with the Licence.
 *
 * You can obtain a copy of the licence at RISC OS path @.^.LICENCE
 * or  http://www.riscosdev.com/lanman98/LICENCE.CDDL
 * See the Licence for the specific language governing permissions
 * and limitations under the Licence.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the Licence file. If applicable, add the
 * following below this CDDL HEADER, with the fields enclosed by
 * brackets "[]" replaced with your own identifying information:
 * Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
 
/*
 *   Portions Copyright 1996 Warm Silence Software Ltd.
 */

#include "kernel.h"
#include "swis.h"
#include <stdlib.h>
#include <string.h>
#include "PGptr.h"

#include "hg_code.h"

static _kernel_swi_regs regs;
static int on = 1;
static int shape = 1;
static int linked = 1;



static void def_ptr(void)
{
    regs.r[0] = 106;
    regs.r[1] = (on?shape:0)|(linked?0:0x80);
    _kernel_swi(OS_Byte, &regs, &regs);
}

void PtrOff(void)
{
    on = 0;
    def_ptr();
}

void PtrOn(void)
{
    on = 1;
    def_ptr();
}

void PtrSetXY(int x, int y)
{
    char buf[5];

    buf[0] = 5;
    buf[1] = x;
    buf[2] = (x >> 8);
    buf[3] = y;
    buf[4] = (y >> 8);
    regs.r[0] = 21;
    regs.r[1] = (int) buf;
    _kernel_swi(OS_Word, &regs, &regs);
}

void PtrGetXY(int *x, int *y)
{
    char buf[5];

    buf[0] = 6;
    regs.r[0] = 21;
    regs.r[1] = (int) buf;
    _kernel_swi(OS_Word, &regs, &regs);
    *x = (buf[1] | (buf[2]<<8));
    *y = (buf[3] | (buf[4]<<8));
}

void PtrSetShape(spr_sprite spr, int activex, int activey)
{
    char buf[10];
    sprmem_t sprmem;
    int x, y;

    if(spr != NULL)
    {
        shape = 2;
        sprmem = SprDirect(spr);
        SprGetSize(spr, &x, &y);
        buf[0] = 0;
        buf[1] = shape;
        buf[2] = sprmem.yinc;
        buf[3] = y / 2;
        buf[4] = activex;
        buf[5] = activey;
        memcpy(buf + 6, &(sprmem.base), sizeof(int));
        regs.r[0] = 21;
        regs.r[1] = (int) buf;
        _kernel_swi(OS_Word, &regs, &regs);
    }
    else
    {
        shape = 1;
    }
    def_ptr();
}

void PtrSetCols(int col1, int col2, int col3)
{
    char buf[5];

    regs.r[0] = 12;
    regs.r[1] = (int) buf;
    buf[0] = 1;
    buf[1] = 25;
    buf[2] = col1;
    buf[3] = (col1<<8); /* Ignores high bytes ?? */
    buf[4] = (col1<<16);
    _kernel_swi(OS_Word, &regs, &regs);
    buf[0] = 2;
    buf[2] = col2;
    buf[3] = (col2<<8);
    buf[4] = (col2<<16);
    _kernel_swi(OS_Word, &regs, &regs);
    buf[0] = 3;
    buf[2] = col3;
    buf[3] = (col3<<8);
    buf[4] = (col3<<16);
    _kernel_swi(OS_Word, &regs, &regs);
}

void PtrLink(int link)
{
    linked = link;
    def_ptr();
}

void PtrAnimate(spr_sprite *spr, int nsprs, int duration,
                                int xactive, int yactive)
{
    static char *buf = NULL;
    char *bufptr;
    sprmem_t sprmem;
    int x, y;
    int i;
    
    if(buf != NULL)
    {
        hg(NULL, NULL, 0);
        free(buf);
        buf = NULL;
    }
    if(nsprs > 0)
    {
        buf = malloc(10 * nsprs);
        if(buf == NULL) return;
        bufptr = buf;
        for(i = 0; i < nsprs; i++)
        {
            sprmem = SprDirect(spr[i]);
            SprGetSize(spr[i], &x, &y);
            bufptr[0] = 0;
            bufptr[2] = sprmem.yinc;
            bufptr[3] = y / 2;
            bufptr[4] = xactive;
            bufptr[5] = yactive;
            memcpy(bufptr + 6, &(sprmem.base), sizeof(int));
            bufptr += 10;
        }
        hg(buf, buf + 10 * nsprs, duration);
    }
}

void MouseSetXY(int x, int y)
{
    char buf[5];

    buf[0] = 3;
    buf[1] = x;
    buf[2] = (x >> 8);
    buf[3] = y;
    buf[4] = (y >> 8);
    regs.r[0] = 21;
    regs.r[1] = (int) buf;
    _kernel_swi(OS_Word, &regs, &regs);
}

void MouseGetXY(int *x, int *y)
{
    char buf[5];

    buf[0] = 4;
    regs.r[0] = 21;
    regs.r[1] = (int) buf;
    _kernel_swi(OS_Word, &regs, &regs);
    *x = (buf[1] | (buf[2]<<8));
    *y = (buf[3] | (buf[4]<<8));
}

void MouseSetBBox(int x0, int y0, int x1, int y1)
{
    char buf[9];

    regs.r[0] = 21;
    regs.r[1] = (int) buf;
    buf[0] = 1;
    buf[1] = x0;
    buf[2] = (x0>>8);
    buf[3] = y0;
    buf[4] = (y0>>8);
    buf[5] = x1;
    buf[6] = (x1>>8);
    buf[7] = y1;
    buf[8] = (y1>>8);
    _kernel_swi(OS_Word, &regs, &regs);
}
