This is the verbatim text of the QwSpriteField.h include file. It is is provided only for illustration; the copyright remains with
// QwSpriteField and associated classes, using Qt C++ class library. // // Author: Warwick Allison (warwick@troll.no) // Date: 19/10/97 // Copyright (C) 1995-97 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 <qscrbar.h> #include <qlist.h> class QwSprite; class QwChunkRec; class QwSpriteField; class QwAbsSpriteFieldView { public: QwAbsSpriteFieldView(QwSpriteField* viewing=0); void view(QwSpriteField*); virtual QRect viewArea() const=0; virtual bool preferDoubleBuffering() const=0; virtual void beginPainter(QPainter&)=0; virtual void flush(const QRect& area)=0; protected: QwSpriteField* viewing; }; class QwSpriteFieldView : public QWidget, public QwAbsSpriteFieldView { Q_OBJECT public: QwSpriteFieldView(QwSpriteField* viewing=0, QWidget* parent=0, const char* name=0, WFlags f=0); ~QwSpriteFieldView(); virtual QRect viewArea() const; virtual bool preferDoubleBuffering() const; virtual void beginPainter(QPainter&); virtual void flush(const QRect& area); protected: // Cause Update for this widget virtual void paintEvent(QPaintEvent *); }; class QwScrollingSpriteFieldView : public QWidget, public QwAbsSpriteFieldView { Q_OBJECT public: QwScrollingSpriteFieldView(QwSpriteField* viewing=0, QWidget* parent=0, const char* name=0, WFlags f=0); ~QwScrollingSpriteFieldView(); virtual QRect viewArea() const; virtual bool preferDoubleBuffering() const; virtual void beginPainter(QPainter&); virtual void flush(const QRect& area); protected: // Cause Update for this widget virtual void paintEvent(QPaintEvent *); virtual void resizeEvent(QResizeEvent *); virtual int hSteps() const; virtual int vSteps() const; protected slots: void vScroll(int); void hScroll(int); private: QPixmap offscr; QScrollBar hscroll; QScrollBar vscroll; int vscrpv; int hscrpv; }; class QwSpriteFieldGraphic { public: static void setCurrentSpriteField(QwSpriteField*); // Alternatively, Graphics can be individually placed on QwSpriteFields. void setSpriteField(QwSpriteField*); QwSpriteFieldGraphic(); virtual ~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* spritefield; // 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); private: static QwSpriteField* current_spritefield; bool vis; }; class QwSpriteField { public: QwSpriteField(); QwSpriteField(int w, int h, int chunksize=16, int maxclusters=100); virtual ~QwSpriteField(); // Call this after some amount of QwSpriteFieldGraphic motion. void update(); virtual void resize(int width, int height); int width() const { return awidth; } int height() const { return aheight; } int chunkSize() const { return chunksize; } void retune(int chunksize, int maxclusters); // (x,y) is *world* position, (i,j) is chunk coordinate. Pix all(); Pix topAt(int x, int y); Pix lookIn(int x, int y, int w, int h); void next(Pix&) const; void end(Pix& p) const; // 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) const; void* allList(); 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 QwAbsSpriteFieldView to call void addView(QwAbsSpriteFieldView*); void removeView(QwAbsSpriteFieldView*); void updateInView(QwAbsSpriteFieldView*, const QRect&); // pre: view has been added // These are for QwSpriteFieldGraphic to call void addGraphic(QwSpriteFieldGraphic*); void removeGraphic(QwSpriteFieldGraphic*); 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) const; QwChunkRec& chunkContaining(int x, int y) const; void drawArea(const QRect&, bool only_changes, QwAbsSpriteFieldView* one_view); int awidth,aheight; int chunksize; int maxclusters; int chwidth,chheight; QwChunkRec* chunks; QList<QwAbsSpriteFieldView> viewList; QList<QwSpriteFieldGraphic> graphicList; static unsigned int posprec; static bool double_buffer; }; class QwSpritePixmap : public QPixmap { public: QwSpritePixmap(const char* datafilename, const char* maskfilename); QwSpritePixmap(const QPixmap&, QPoint hotspot); ~QwSpritePixmap(); int hotX() const { return hotx; } int hotY() const { return hoty; } 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=100); virtual ~QwImageSpriteField(); protected: virtual void drawBackground(QPainter&, const QRect& area); private: QPixmap image; }; class QwSpritePixmapSequence { public: QwSpritePixmapSequence(const char* datafilenamepattern, const char* maskfilenamepattern, int framecount=1); QwSpritePixmapSequence(QList<QPixmap>, QList<QPoint> hotspots); ~QwSpritePixmapSequence(); 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() const; Pix neighbourhood(int nx, int ny) const; Pix neighbourhood(int nx, int ny, QwSpritePixmap*) const; // void next(Pix&) const; void end(Pix& p) const; // 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; int absX(int nx) const; int absY(int ny) const; int absX2(int nx) const; int absY2(int ny) 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) const; // Neighbourhood if Frame(frame). Pix neighbourhood(int nx, int ny) const { return QwVirtualSprite::neighbourhood(nx,ny); } Pix neighbourhood(COORD nx, COORD ny, int frame) const; // 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 adoptSpritefieldBounds(); 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; } COORD dX() const { return dx; } COORD dY() const { return dy; } void forward(COORD multiplier); void forward(COORD multiplier, int frame); Pix forwardHits(COORD multiplier) const; Pix forwardHits(COORD multiplier, int frame) const; void moveTo(COORD x, COORD y) { QwPositionedSprite<COORD>::moveTo(x,y); } 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>() { } }; class QwPolygonalGraphic : public QwSpriteFieldGraphic { public: QwPolygonalGraphic(); virtual ~QwPolygonalGraphic(); virtual int numAreaPoints() const=0; virtual void getAreaPoints(QPoint pt[]) const=0; virtual int rtti() const; protected: virtual void makeVisible(bool yes); // Call these either side of numAreaPoints() or getAreaPoints() value changes. void addToChunks(); void removeFromChunks(); }; class QwTextSprite : public QwSpriteFieldGraphic { public: QwTextSprite(); QwTextSprite(const char*); QwTextSprite(const char*, QFont); virtual ~QwTextSprite(); void setText( const char* ); void setFont( const QFont& ); void setColor( const QColor& ); void x(int); void y(int); void z(int); void moveBy(int dx, int dy); void moveTo(int x, int y); int x() const { return ox; } int y() const { return oy; } int z() const; int textFlags() const { return flags; } void setTextFlags(int); const QRect& boundingRect() { return brect; } bool at(int, int) const; bool at(const class QRect &) const; virtual int rtti() const; 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(); private: void changeChunks(); void setRect(); int alt; int ox, oy; QRect brect; QString text; int flags; QFont font; QColor col; }; #endif