[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

/* The listing given here shows a complete VSprite example.  This
** program requires the animtools.c, animtools.h and animtools_proto.h
** support files in order to compile and run.  These files are listed at
** the end of this chapter.
**
** vsprite.c
**
** SAS/C V5.10a
** lc -b1 -cfist -v -y vsprite.c
** blink FROM LIB:c.o vsprite.o animtools.o LIB LIB:lc.lib LIB:amiga.lib TO vsprite
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/gels.h>
#include <graphics/collide.h>
#include <libraries/dos.h>
#include <stdlib.h>
#include "animtools.h"

VOID borderCheck(struct VSprite *hitVSprite, LONG borderflags);
VOID process_window(struct Window *win, struct RastPort *myRPort, struct VSprite *MyVSprite);
VOID do_VSprite(struct Window *win, struct RastPort *myRPort);
VOID vspriteDrawGList(struct Window *win, struct RastPort *myRPort);

struct GfxBase		 *GfxBase;   /* pointer to Graphics library  */
struct IntuitionBase *IntuitionBase; /* pointer to Intuition library */

int return_code;
#define GEL_SIZE	4 /* number of lines in the vsprite */

/* VSprite data - there are two sets that are alternated between. */
/* note that this data is always displayed as low resolution.	  */
WORD chip vsprite_data1[] = { 0x7ffe, 0x80ff,
                              0x7c3e, 0x803f,
                              0x7c3e, 0x803f,
                              0x7ffe, 0x80ff,
                              0, 0 };

WORD chip vsprite_data2[] = { 0x7ffe, 0xff01,
                              0x7c3e, 0xfc01,
                              0x7c3e, 0xfc01,
                              0x7ffe, 0xff01,
                              0, 0 };

WORD mySpriteColors[] =     { 0x0000, 0x00f0, 0x0f00 };
WORD mySpriteAltColors[] =  { 0x000f, 0x0f00, 0x0ff0 };

NEWVSPRITE myNewVSprite = {              /* information for the new VSprite       */
        /* Image data, sprite color array word width (must be 1 for true VSprite) */
        vsprite_data1, mySpriteColors,1,
        /* Line height, image depth (must be 2 for true VSprite), x, y position   */                                                           */
        GEL_SIZE, 2, 160, 100,
        /* Flags (VSPRITE == true VSprite), hit mask and me mask                  */
        VSPRITE, 1 << BORDERHIT, 0
        };

struct NewWindow myNewWindow = {        /* information for the new window */
    80, 20, 400, 150, -1, -1, CLOSEWINDOW | INTUITICKS,
    ACTIVATE | WINDOWCLOSE | WINDOWDEPTH | RMBTRAP | WINDOWDRAG,
    NULL, NULL, "VSprite", NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN
    };

/* Basic VSprite display subroutine */
VOID vspriteDrawGList(struct Window *win, struct RastPort *myRPort)
{
SortGList(myRPort);
DrawGList(myRPort, ViewPortAddress(win));
RethinkDisplay();
}

/* Collision routine for vsprite hitting border.  Note that when the collision is VSprite to */
/* VSprite (or Bob to Bob, Bob to AnimOb, etc), then the parameters are both pointers to a VSprite. */
VOID borderCheck(struct VSprite *hitVSprite, LONG borderflags)
{
if (borderflags & RIGHTHIT)
    {
    hitVSprite->SprColors = mySpriteAltColors;
    hitVSprite->VUserExt  = -40;
    }
if (borderflags & LEFTHIT)
    {
    hitVSprite->SprColors = mySpriteColors;
    hitVSprite->VUserExt  = 20;
    }
}

/* Process window and dynamically change vsprite. Get messages. Go away on           */
/* CLOSEWINDOW.  Update and redisplay vsprite on INTUITICKS. Wait for more messages. */
VOID process_window(struct Window *win, struct RastPort *myRPort, struct VSprite *myVSprite)
{
struct IntuiMessage *msg;

FOREVER
    {
    Wait(1L << win->UserPort->mp_SigBit);
    while (NULL != (msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
        {
        /* Only CLOSEWINDOW and INTUITICKS are active */
        if (msg->Class == CLOSEWINDOW)
            {
            ReplyMsg((struct Message *)msg);
            return;
            }
        /* Must be an INTUITICKS:  change x and y values on the fly.  Note offset by
        ** window left and top edge--sprite relative to the screen, not window.  Divide
        ** the MouseY in half to adjust for Lores movement increments on a Hires screen.
        */
        myVSprite->X = win->LeftEdge + msg->MouseX + myVSprite->VUserExt;
        myVSprite->Y = win->TopEdge  + msg->MouseY/2 + 1;
        ReplyMsg((struct Message *)msg);
        }
    /* Got a message, change image data on the fly */
    myVSprite->ImageData = (myVSprite->ImageData == vsprite_data1) ? vsprite_data2 : vsprite_data1;
    SortGList(myRPort);
    DoCollision(myRPort);
    vspriteDrawGList(win, myRPort);
    }
}

/* Working with the VSprite.  Setup the GEL system and get a new VSprite (makeVSprite()).   */
/* Add VSprite to the system and display.  Use the vsprite.  When done, remove VSprite and  */
/* update the display without the VSprite.  Cleanup everything.                             */
VOID do_VSprite(struct Window *win, struct RastPort *myRPort)
{
struct VSprite       *myVSprite;
struct GelsInfo       *my_ginfo;

if (NULL == (my_ginfo = setupGelSys(myRPort, 0xfc)))
    return_code = RETURN_WARN;
else
    {
    if (NULL == (myVSprite = makeVSprite(&myNewVSprite)))
        return_code = RETURN_WARN;
    else
        {
        AddVSprite(myVSprite, myRPort);
        vspriteDrawGList(win, myRPort);
        myVSprite->VUserExt = 20;
        SetCollision(BORDERHIT, borderCheck, myRPort->GelsInfo);
        process_window(win, myRPort, myVSprite);
        RemVSprite(myVSprite);
        freeVSprite(myVSprite);
        }
    vspriteDrawGList(win, myRPort);
    cleanupGelSys(my_ginfo, myRPort);
    }
}

/* Example VSprite program.  First open up the libraries and a window. */
VOID main(int argc, char **argv)
{
struct Window       *win;
struct RastPort    myRPort = {0};

return_code = RETURN_OK;

if (NULL == (GfxBase = (struct GfxBase *)OpenLibrary(GRAPHICSNAME,37L)))
    return_code = RETURN_FAIL;
else
    {
    if (NULL == (IntuitionBase = (struct IntuitionBase *)OpenLibrary(INTUITIONNAME,37L)))
        return_code = RETURN_FAIL;
    else
        {
        if (NULL == (win = OpenWindow(&myNewWindow)))
            return_code = RETURN_WARN;
        else
            {
            InitRastPort(&myRPort);
            myRPort = win->WScreen->RastPort;       /* Copy the structure. */
            do_VSprite(win, &myRPort);
            CloseWindow(win);
            }
        CloseLibrary((struct Library *)IntuitionBase);
        }
    CloseLibrary((struct Library *)GfxBase);
    }
exit(return_code);
}