Back to index

kdeartwork  4.3.2
Classes | Public Member Functions | Private Slots | Private Attributes
Screen Class Reference

This is the main display class of Asciiquarium. More...

#include <screen.h>

Collaboration diagram for Screen:
Collaboration graph
[legend]

List of all members.

Classes

struct  Pixel
 Represents a logical character on the Screen. More...

Public Member Functions

 Screen (AASaver *widget)
 Constructor.
 ~Screen ()
int width () const
 Returns the logical width of the screen.
int height () const
 Returns the logical height of the screen.
int cellWidth () const
 Returns the GUI width of a character cell.
int cellHeight () const
 Returns the GUI height of a character cell.
void addSprite (Sprite *sprite)
 Adds a sprite to the internal sprite list.
int msPerTick () const
 Returns the number of milliseconds separating each animation tick.
void updateSpan (int x, int y, const QPixmap &updatePixmap)
 Updates the backbuffer, and asks the portion of the widget to be repainted.
void clearSpan (int x, int y, const QPixmap &clearPixmap)
 Clear the given portion of the backbuffer, asks for a repaint.
void paint (QPaintEvent *pe)
 Actually paints the scene on the widget.

Private Slots

void doAnimate ()
 Handles updating the screen buffer to draw the next frame.

Private Attributes

AASaverm_widget
 Widget that we should paint on.
int m_width
 Number of logical columns in the screen.
int m_height
 Number of logical rows on the screen.
int m_offX
 Number of pixels on left side needed to center image.
int m_offY
 Number of pixels on top side needed to center image.
QPixmap m_backBuffer
 Pixmap cache of the image used to speed up rendering.
QPainter * m_curPainter
int m_cellW
 The GUI width of a character cell.
int m_cellH
 The GUI height of a character cell.
QList< Sprite * > m_sprites
 List of Sprites on screen.
QList< Sprite * > m_addedSprites
 List of Sprites to be added next frame.

Detailed Description

This is the main display class of Asciiquarium.

We use a pseudo-terminal-ish type coordinate system, where although this is a full fledged GUI application, Sprites and most external functions deal with logical text position coordinates instead of GUI coordinates. (x, y) starts in the upper-left of the real screen at (0, 0), and continues on to (width - 1, height - 1).

Use addSprite() to add new Sprites to the Screen after you have created them and added their Frames.

Definition at line 50 of file screen.h.


Constructor & Destructor Documentation

Screen::Screen ( AASaver widget)

Constructor.

Parameters:
widgetThe widget to draw on.

Definition at line 43 of file screen.cpp.

                             : m_widget(widget), m_curPainter(0)
{
    QFontMetrics fm(KGlobalSettings::fixedFont());

    // Compute cell geometries.
    m_cellW  = fm.maxWidth();
    m_cellH  = fm.lineSpacing();

    // Computer number of full cells that will fit.
    m_width  = widget->width()  / m_cellW;
    m_height = widget->height() / m_cellH;

    // Calculate offset needed to evenly distribute excess screen space.
    m_offX = (widget->width() - m_width * m_cellW) / 2;
    m_offY = (widget->height() - m_height * m_cellH) / 2;

    // Setup animation timer.
    QTimer* timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), m_widget, SLOT(update()));

    timer->start(msPerTick());
}

Here is the call graph for this function:

Definition at line 71 of file screen.cpp.

{
}

Member Function Documentation

void Screen::addSprite ( Sprite sprite) [inline]

Adds a sprite to the internal sprite list.

Parameters:
spriteThe Sprite to add. It will show up in the next frame.

Definition at line 132 of file screen.h.

    {
        m_addedSprites.append(sprite);
    }

Here is the caller graph for this function:

int Screen::cellHeight ( ) const [inline]

Returns the GUI height of a character cell.

Definition at line 122 of file screen.h.

    {
        return m_cellH;
    }

Here is the caller graph for this function:

int Screen::cellWidth ( ) const [inline]

Returns the GUI width of a character cell.

Definition at line 116 of file screen.h.

    {
        return m_cellW;
    }

Here is the caller graph for this function:

void Screen::clearSpan ( int  x,
int  y,
const QPixmap &  clearPixmap 
)

Clear the given portion of the backbuffer, asks for a repaint.

Parameters:
xThe logical x coordinate of the left edge of the update region.
yThe logical y coordinate of the top edge of the update region.
clearPixmapthe pixmap to use to clear the span, which should be the background color of the Screen, and masked to only draw the area that needs cleared.

Definition at line 84 of file screen.cpp.

{
    if (y < 0 || y >= m_height)
        return;

    QPoint upperLeft(m_offX + x * m_cellW, m_offY + y * m_cellH);
    m_curPainter->fillRect(QRect(upperLeft, clearPixmap.size()), Qt::black);
}

Here is the caller graph for this function:

void Screen::doAnimate ( ) [private, slot]

Handles updating the screen buffer to draw the next frame.

Definition at line 147 of file screen.cpp.

{
    //First, rebuild a new list of sprites, and build a dirty region
    QRegion dirtyRegion;

    QList<Sprite*> sprites;
    QList<Sprite*> colliders;

    // Look for sprites that can suffer a collision.
    foreach(Sprite *sprite, m_sprites) {
        if(sprite->canCollide())
            colliders.append(sprite);
    }

    // Find collisions.
    // FIXME: Use transparent regions for accuracy.
    foreach(Sprite *collider, colliders) {
        foreach(Sprite *sprite, m_sprites) {
            // Can't collide with yourself...
            if(sprite == collider)
                continue;

            if(collider->geom().intersects(sprite->geom()))
                collider->collision(sprite);
        }
    }

    //Retain all live existing sprites
    foreach(Sprite *sprite, m_sprites) {
        QRect oldRect = sprite->geom();

        if (!sprite->isKilled()) {
            bool dirty = sprite->tickUpdate();

            if (dirty)
                dirtyRegion |= oldRect | sprite->geom();

            if (!sprite->isKilled())
                sprites.append(sprite);
        }

        if (sprite->isKilled()) //note:may be made true by updateTick!
        {
            dirtyRegion |= oldRect;
            delete sprite;
        }
    }

    //Add new sprites.
    foreach(Sprite *sprite, m_addedSprites) {
        dirtyRegion |= sprite->geom();
        sprites.append(sprite);
    }

    m_addedSprites.clear();
    m_sprites = sprites;

    //Compute the list of sprites affected. Note that this is
    //done iteratively until fixed point.
    QList<Sprite*> paintSprites;
    QList<Sprite*> remSprites;

    bool changed;
    do
    {
        changed = false;
        remSprites.clear();

        foreach(Sprite *sprite, sprites) {
            if (dirtyRegion.intersect(sprite->geom()).isEmpty())
                remSprites.append(sprite); //not to be painted thus far
            else
            {
                //This sprite is to be painted
                paintSprites.append(sprite);

                //make sure we repaint everything overlapping it
                dirtyRegion |= sprite->geom();
                changed = true;
            }
        }

        sprites = remSprites;
    }
    while (changed);

    //Z-sort the items.
    QMap<ZKey, Sprite* > sorted;
    foreach(Sprite *sprite, paintSprites)
        sorted[ZKey(sprite)] = sprite;

    //Paint, in Z-order
    foreach(Sprite *sprite, sorted)
        sprite->paint();
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Screen::height ( ) const [inline]

Returns the logical height of the screen.

Definition at line 110 of file screen.h.

    {
        return m_height;
    }

Here is the caller graph for this function:

int Screen::msPerTick ( ) const

Returns the number of milliseconds separating each animation tick.

Definition at line 66 of file screen.cpp.

{
    return 50;
}

Here is the caller graph for this function:

void Screen::paint ( QPaintEvent *  pe)

Actually paints the scene on the widget.

Parameters:
peThe QPaintEvent given to the updating widget.

Definition at line 94 of file screen.cpp.

{
    if(m_backBuffer.isNull()) {
        m_backBuffer = QPixmap(m_widget->size());
        m_backBuffer.fill(Qt::black);
    }

    { // Artificial scoping for the QPainter
        QPainter p(&m_backBuffer);

        // XXX: This is a hack to allow updateSpan and clearSpan access to the
        // current QPainter.  Could use some re-architecting.  This sequence
        // draws onto the back buffer.
        m_curPainter = &p;
        doAnimate();
        m_curPainter = 0;
    }

    // Draw onto the main widget now.
    QPainter p(m_widget);
    p.setCompositionMode(QPainter::CompositionMode_Source); // bitBlt ftw
    p.drawPixmap(0, 0, m_backBuffer);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Screen::updateSpan ( int  x,
int  y,
const QPixmap &  updatePixmap 
)

Updates the backbuffer, and asks the portion of the widget to be repainted.

Parameters:
xThe logical x coordinate of the left edge of the update area.
yThe logical y coordinate of the top edge of the update area.
updatePixmapThe pixmap to draw into the buffer, which should be masked to only draw non-transparent regions.

Definition at line 75 of file screen.cpp.

{
    if (y < 0 || y >= m_height)
        return;

    QPoint upperLeft(m_offX + x * m_cellW, m_offY + y * m_cellH);
    m_curPainter->drawPixmap(upperLeft, updatePixmap);
}

Here is the caller graph for this function:

int Screen::width ( ) const [inline]

Returns the logical width of the screen.

Definition at line 104 of file screen.h.

    {
        return m_width;
    }

Here is the caller graph for this function:


Member Data Documentation

QList<Sprite*> Screen::m_addedSprites [private]

List of Sprites to be added next frame.

Definition at line 86 of file screen.h.

QPixmap Screen::m_backBuffer [private]

Pixmap cache of the image used to speed up rendering.

All paints happen to the pixmap, which is then bitBlt()'ed to m_widget when the time comes to paint.

Definition at line 79 of file screen.h.

int Screen::m_cellH [private]

The GUI height of a character cell.

Definition at line 83 of file screen.h.

int Screen::m_cellW [private]

The GUI width of a character cell.

Definition at line 82 of file screen.h.

QPainter* Screen::m_curPainter [private]

Definition at line 80 of file screen.h.

int Screen::m_height [private]

Number of logical rows on the screen.

Definition at line 71 of file screen.h.

int Screen::m_offX [private]

Number of pixels on left side needed to center image.

Definition at line 72 of file screen.h.

int Screen::m_offY [private]

Number of pixels on top side needed to center image.

Definition at line 73 of file screen.h.

QList<Sprite*> Screen::m_sprites [private]

List of Sprites on screen.

Definition at line 85 of file screen.h.

Widget that we should paint on.

Definition at line 69 of file screen.h.

int Screen::m_width [private]

Number of logical columns in the screen.

Definition at line 70 of file screen.h.


The documentation for this class was generated from the following files: