This is the verbatim text of the QwSpriteField.h include file.


// QwSpriteField and associated classes, using Qt C++ class library.
//    class QwSpriteField
//    class QwImageSpriteField : public QwSpriteField
//    class QwSpriteFieldView : public QWidget
//
//    class QwSpriteFieldGraphic
//    class QwVirtualSprite : public QwSpriteFieldGraphic
//    class QwSprite : public QwVirtualSprite
//
//    class QwSpritePixmap : public QPixmap
//    class QwSpritePixmapSequence
//
// Author: Warwick Allison (warwick@cs.uq.edu.au)
//   Date: 26/03/96
// Copyright (C) 1995-96 by Warwick Allison.
//

#ifndef QwSpriteField_H
#define QwSpriteField_H

#include <Pix.h> // GNU libg++ `Pix' concept (it's just a void*).

#include <qbitmap.h>
#include <qwidget.h>
#include <qlist.h>

class QwSprite;
class QwSpriteFieldGraphic;
class QwChunkRec;
class QwSpriteField;

class QwSpriteFieldView : public QWidget
{
public:
        QwSpriteFieldView(QwSpriteField* viewing=0, QWidget* parent=0, const char* name=0, WFlags f=0);
        ~QwSpriteFieldView();

        void view(QwSpriteField*);

        virtual QRect viewArea() const;

protected:
        // Cause Update for this widget
        virtual void paintEvent(QPaintEvent *);

private:
        QwSpriteField* viewing;
};


class QwSpriteField
{
public:
        QwSpriteField(int w, int h, int chunksize=16, int maxclusters=20);
        virtual ~QwSpriteField();

        // Call this after some amount of QwSpriteFieldGraphic motion.
        void update();

        void resize(int width, int height);
        int width() const { return awidth; }
        int height() const { return aheight; }
        int chunkSize() const { return chunksize; }

        // (x,y) is *world* position, (i,j) is chunk coordinate.

        Pix topAt(int x, int y);
        Pix lookIn(int x, int y, int w, int h);
        void next(Pix&);
        void end(Pix& p); // need not be called for p==0
        QwSpriteFieldGraphic* at(Pix p) const;
        bool exact(Pix p) const; // Pre: (p && At(p))
        void protectFromChange(Pix p);

        bool sameChunk(int x1, int y1, int x2, int y2) const
                { return x1/chunksize==x2/chunksize && y1/chunksize==y2/chunksize; }
        void setChangedChunk(int i, int j);
        void setChangedChunkContaining(int x, int y);

        // These call setChangedChunk
        void addGraphicToChunk(QwSpriteFieldGraphic*, int i, int j);
        void removeGraphicFromChunk(QwSpriteFieldGraphic*, int i, int j);
        void addGraphicToChunkContaining(QwSpriteFieldGraphic*, int x, int y);
        void removeGraphicFromChunkContaining(QwSpriteFieldGraphic*, int x, int y);

        // This is internal.
        void* listAtChunkTopFirst(int i, int j);

        static void setPositionPrecision(int downshifts) { posprec=downshifts; }
        static int positionPrecision() { return posprec; }
        static int world_to_x(int i) { return i>>posprec; }
        static int x_to_world(int i) { return i<<posprec; }

        // These are for QwSpriteFieldView to use
        void addView(QwSpriteFieldView*);
        void removeView(QwSpriteFieldView*);
        void updateInView(QwSpriteFieldView*, const QRect&); // pre: view has been added

protected:
        virtual void drawBackground(QPainter&, const QRect& area);
        virtual void drawForeground(QPainter&, const QRect& area);

        void forceRedraw(const QRect&);

private:
        QwChunkRec& chunk(int i, int j);
        QwChunkRec& chunkContaining(int x, int y);

        void drawArea(const QRect&, bool only_changes, QwSpriteFieldView* one_view);

        int awidth,aheight;
        const int chunksize;
        const int maxclusters;
        int chwidth,chheight;
        QwChunkRec* chunks;

        QList<QwSpriteFieldView> viewList;

        static unsigned int posprec;
};


class QwSpritePixmap : public QPixmap
{
public:
        QwSpritePixmap(const char* datafilename, const char* maskfilename);
        ~QwSpritePixmap();

private:
        friend class QwVirtualSprite;
        friend class QwSpritePixmapSequence;
        friend class QwSpriteFieldIterator;

        int hotx,hoty;

        QImage* collision_mask;
        int colw,colh;
        int colhotx,colhoty;

        QBitmap mask;
};


class QwImageSpriteField : public QwSpriteField
{
public:
        QwImageSpriteField(const char* imagefile, int w, int h, int chunksize=16, int maxclusters=20);
        virtual ~QwImageSpriteField();

protected:
        virtual void drawBackground(QPainter&, const QRect& area);

private:
        QPixmap image;
};

class QwSpriteFieldGraphic
{
public:
        static void setCurrentSpriteField(QwSpriteField*);

        // Alternatively, Graphics can be individually placed on QwSpriteFields.
        void setSpriteField(QwSpriteField*);

        QwSpriteFieldGraphic();

        virtual int z() const=0;

        virtual void draw(QPainter&)=0;

        void show();
        void hide();
        void visible(bool yes);
        bool visible() const; // initially true for QwSpriteFieldGraphics

        // true iff the graphic includes the given pixel position.
        virtual bool at(int x, int y) const=0;
        // true iff the graphic intersects with the given area.
        virtual bool at(const QRect& rect) const=0;
        // true iff the graphic intersects with the given bitmap.
        //   rect gives the offset of the bitmap and relevant area.
        // The default is to just call At(const QRect& rect) above.
        virtual bool at(const QImage* image, const QRect& rect) const;

        virtual int rtti() const;

protected:
        QwSpriteField* playfield;

        // Visible() will always be true when this is called, as it will
        // be changed before the call when showing and after when hiding.
        // Note, may also be called while moving between QwSpriteFields
        // (see SetSpriteField), such that the QwSpriteFieldGraphic is not visible when
        // moved (conceptually, invisibility is not being on any QwSpriteField).
        virtual void makeVisible(bool yes);

        static int world_to_x(int i) { return QwSpriteField::world_to_x(i); }
        static int x_to_world(int i) { return QwSpriteField::x_to_world(i); }

private:
        static QwSpriteField* current_playfield;
        bool vis;
};


class QwSpritePixmapSequence
{
public:
        QwSpritePixmapSequence(const char* datafilenamepattern,
                const char* maskfilenamepattern, int framecount=1);

        void readCollisionMasks(const char* filenamepattern);

        int operator!(); // Failure check.

        QwSpritePixmap* image(int i) const { return img[i]; }
        int frameCount() const { return framecount; }

private:
        int framecount;
        QwSpritePixmap** img;
};


class QwVirtualSprite : public QwSpriteFieldGraphic
{
public:
        QwVirtualSprite();

        virtual ~QwVirtualSprite();

        // Reduce collision precision by right-shifting effective coordinates.
        // by the given amount.  Negative values can be used, in which case 
        // the resolution is increased (not often useful).  (default==0)
        //
        static void setPixelCollisionPrecision(int downshifts);

        int width() const;
        int height() const;
        int colWidth() const;
        int colHeight() const;

        // These components must be provided by concrete subclasses.
        // Note the usage of AddToChunks and RemoveFromChunks protected methods.
        //
        virtual QwSpritePixmap* image() const=0;
        virtual int x() const=0;
        virtual int y() const=0;

        virtual bool at(int x, int y) const;
        virtual bool at(const QRect& rect) const;
        virtual bool at(const QImage* image, const QRect& rect) const;

        virtual int rtti() const;

        // Traverse intersecting Graphics.
        //
        // See QwSpriteField::TopAt() for more details.
        //
        Pix neighbourhood();
        Pix neighbourhood(int nx, int ny);
        Pix neighbourhood(int nx, int ny, QwSpritePixmap*);
        //
        void next(Pix&);
        void end(Pix& p); // need not be called for p==0
        QwSpriteFieldGraphic* at(Pix p) const;
        bool exact(Pix p) const; // Pre: (p && At(p))

        bool hitting(QwSpriteFieldGraphic&) const;
        bool wouldHit(QwSpriteFieldGraphic&, int x, int y, QwSpritePixmap*) const;

        static int world_to_col(int i) { return i>>colprec; }
        static int col_to_world(int i) { return i<<colprec; }

protected:
        virtual void makeVisible(bool yes);

        virtual void draw(QPainter&);

        // Call these either side of X(), Y(), or Image() value changes.
        void addToChunks();
        void removeFromChunks();

        int absX() const;
        int absY() const;
        int absX2() const;
        int absY2() const;

        int absColX() const;
        int absColY() const;
        int absColX2() const;
        int absColY2() const;

private:
        static unsigned int colprec;
};

template<class COORD>
class QwPositionedSprite : public QwVirtualSprite
{
public:
        QwPositionedSprite(QwSpritePixmapSequence&);

        QwPositionedSprite();
        void setSequence(QwSpritePixmapSequence& seq);

        virtual ~QwPositionedSprite();

        void frame(int); 
        int frame() const { return frm; }
        int frameCount() const { return images->frameCount(); }

        virtual int x() const { return (int)myx; }
        virtual int y() const { return (int)myy; }
        COORD exact_x() const { return myx; }
        COORD exact_y() const { return myy; }
        void x(COORD);
        void y(COORD);
        void moveBy(COORD dx, COORD dy);
        void moveTo(COORD x, COORD y);
        virtual void moveTo(COORD x, COORD y, int frame);
        virtual int z() const { return alt; }
        void z(int a) { alt=a; changeChunks(); }

        virtual int rtti() const;

        Pix neighbourhood(int frame); // Neighbourhood if Frame(frame).
        Pix neighbourhood(COORD nx, COORD ny, int frame); // Both of above.
        bool wouldHit(QwSpriteFieldGraphic&, COORD x, COORD y, int frame) const;

private:
        COORD myx,myy;
        int frm;
        int alt;

        void changeChunks();

        virtual QwSpritePixmap* image() const { return images->image(frm); }
        QwSpritePixmap* image(int f) const { return images->image(f); }

        QwSpritePixmapSequence* images;
};

template <class COORD>
class QwMobilePositionedSprite : public QwPositionedSprite<COORD> {
public:
        QwMobilePositionedSprite(QwSpritePixmapSequence&);
        QwMobilePositionedSprite();

        void bounds(COORD left, COORD top, COORD right, COORD bottom);
        void adoptPlayfieldBounds();

        static const int Ignore=0;
        static const int Stop=1;
        static const int Wrap=2;
        static const int Bounce=3;
        void setBoundsAction(int action);
        bool outOfBounds();

        void setVelocity(COORD dX, COORD dY) { dx=dX; dy=dY; }
        void forward(COORD multiplier);
        void forward(COORD multiplier, int frame);

        virtual void moveTo(COORD x, COORD y, int frame);

private:
        int bounds_action;
        COORD dx,dy;
        COORD b_left, b_top, b_right, b_bottom;
};


// The most common instantiations of the above templates...

class QwSprite : public QwPositionedSprite<int> {
public:
        QwSprite(QwSpritePixmapSequence& s) : QwPositionedSprite<int>(s) { }
        QwSprite() : QwPositionedSprite<int>() { }
};

class QwRealSprite : public QwPositionedSprite<double> {
public:
        QwRealSprite(QwSpritePixmapSequence& s) : QwPositionedSprite<double>(s) { }
        QwRealSprite() : QwPositionedSprite<double>() { }
};

class QwMobileSprite : public QwMobilePositionedSprite<int> {
public:
        QwMobileSprite(QwSpritePixmapSequence& s) : QwMobilePositionedSprite<int>(s) { }
        QwMobileSprite() : QwMobilePositionedSprite<int>() { }
};

class QwRealMobileSprite : public QwMobilePositionedSprite<double> {
public:
        QwRealMobileSprite(QwSpritePixmapSequence& s) : QwMobilePositionedSprite<double>(s) { }
        QwRealMobileSprite() : QwMobilePositionedSprite<double>() { }
};

#endif


Generated at 15:00, 1996/10/21