/*******************************************************************************
 *
 * (c) Copyright 1993 Commodore-Amiga, Inc.  All rights reserved.
 *
 * This software is provided as-is and is subject to change; no warranties
 * are made.  All use is at your own risk.  No liability or responsibility
 * is assumed.
 *
 * sprites.c - allocates sprites and handles sprite movements.
 *
 ******************************************************************************/

#include <exec/types.h>
#include <graphics/sprite.h>
#include <intuition/pointerclass.h>
#include <intuition/classes.h>
#include <intuition/classusr.h>
#include <intuition/screens.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <stdio.h>

#include "playanim.h"
#include "sprites.h"
#include "stick.h"

extern struct BitMap XHairBitMap;
extern struct BitMap MissileBitMap;

APTR InitXHair(void)
{
    /* For the main Cross-hair cursor, use intuition's pointer. NewObject()
     * of the POINTERCLASS informs intuition that we want to change the
     * pointer imagery, width and resolution.
     */

    APTR XHair;

    XHair = NewObject(NULL, POINTERCLASS, 
    	              POINTERA_BitMap, &XHairBitMap,
       	              POINTERA_XOffset, XHAIRXOFFSET,
    	              POINTERA_YOffset, XHAIRYOFFSET,
    	              POINTERA_WordWidth, XHAIRWIDTH,
    	              POINTERA_XResolution, SPRITE_XRESN,
    	              POINTERA_YResolution, SPRITE_YRESN,
    	              TAG_END);

    return(XHair);
}

BOOL InitMissiles(struct Missile *Missile, struct ExtSprite *Sprites[])
{
    LONG num;
    BOOL error = FALSE;
    int i;

    for (i = 0; ((i < SPRITE_COUNT) && !error); i++)
    {
	if ((Sprites[i] = AllocSpriteData(&MissileBitMap,
	                                 SPRITEA_Width, MISSILEWIDTH,
	                                 TAG_END)) == NULL)
	{
		error = TRUE;
	}
    }

    if (error)
    {
	for (i = 0; i < SPRITE_COUNT; i++)
	{
		if (Sprites[i])
		{
			FreeSpriteData(Sprites[i]);
			Sprites[i] = NULL;
		}
	}
	return(FALSE);
    }

    /* start with the first missile image. */
    Missile->mis_Sprite = Sprites[0];
    num = GetExtSprite(Missile->mis_Sprite,
	               GSTAG_SPRITE_NUM, MISSILESPRITENUM,
	               TAG_END);
    for (i = 0; i < SPRITE_COUNT; i++)
    {
	Sprites[i]->es_SimpleSprite.num = num;
    }
    if (num == -1)
    {
	return(FALSE);
    }

    return(TRUE);
}

#define MISSILECOUNT 8
#define MISSILE_X_ORIGIN (input->Screen->Width >> 1)
#define MISSILE_Y_ORIGIN (input->Screen->Height)

void FireMissile(struct Input *input)
{
    struct Missile *Missile = input->Missiles;

    if (!(Missile->mis_Active))
    {
	Missile->mis_StartX = input->Vista->vs_CamX;
	Missile->mis_StartY = input->Vista->vs_CamY;
	Missile->mis_StartZ = input->Vista->vs_CamZ;
	Missile->mis_StartPitch = input->Vista->vs_Pitch;
	MoveSprite(&input->Screen->ViewPort, &Missile->mis_Sprite->es_SimpleSprite, MISSILE_X_ORIGIN, MISSILE_Y_ORIGIN);
	Missile->mis_Active = MISSILECOUNT;
    }
}

void FireAudio(struct Input *input);

void MoveMissile(struct Input *input)
{
    struct Missile *Missile = input->Missiles;
    WORD XPos, YPos;
    WORD time;

    if (--Missile->mis_Active)
    {
	time = (MISSILECOUNT - Missile->mis_Active);
        XPos = (MISSILE_X_ORIGIN + (((input->Screen->MouseX - MISSILE_X_ORIGIN) * time) / MISSILECOUNT));
        YPos = (MISSILE_Y_ORIGIN + (((input->Screen->MouseY - MISSILE_Y_ORIGIN) * time) / MISSILECOUNT));
	MoveSprite(&input->Screen->ViewPort, &Missile->mis_Sprite->es_SimpleSprite, XPos, YPos);
	FireAudio(input);
    }
    else
    {
	MoveSprite(&input->Screen->ViewPort, &Missile->mis_Sprite->es_SimpleSprite, -100, -100);
    }
}
