#include #include "invaders2.h" /*--------------------double buffered graphics-------------------*/ static void setOffScreenPixel(offScreen_t offScreen, unsigned char x, unsigned char y, unsigned char color) { assert(offScreen != 0); assert(x < NUM_COLS); assert(y < NUM_ROWS); assert(color <= NUMPLANE); offScreen[color][y][x / 8u] |= shl_table[x % 8u]; } static void flushOffScreenBuffer(offScreen_t offScreen) { assert(offScreen != 0); /* off-screen blitting borrowed from fixed point math patterns animation, see fpmath_patterns.c (fixDrawPattern(...) for details */ unsigned char *pPixmap = (&pixmap[NUMPLANE - 1][NUM_ROWS - 1][LINEBYTES - 1]) + 1; unsigned char *pOffScreenDistHigh = (&offScreen[NUMPLANE][NUM_ROWS - 1][LINEBYTES - 1]) + 1; unsigned char *pOffScreenDistLow = (&offScreen[NUMPLANE - 1][NUM_ROWS - 1][LINEBYTES - 1]) + 1; while (pPixmap != &pixmap[0][0][0]) // stop at the beginning { *(--pPixmap) = *(--pOffScreenDistHigh); *(--pOffScreenDistLow) |= *pOffScreenDistHigh; *pOffScreenDistHigh = 0; } } /*----------------------getter/setter----------------------------*/ unsigned char getInvaderPixel(Invaders * iv, unsigned char x, unsigned char y) { if (((x - iv->pos.x) < MAX_INVADER_WIDTH) && ((x - iv->pos.x) >= 0) && ((y - iv->pos.y) < MAX_INVADER_HEIGHT) && ((y - iv->pos.y) >= 0)) { return iv->map[x - iv->pos.x][y - iv->pos.y]; } return 0; } void setInvaderPixel(Invaders * iv, unsigned char x, unsigned char y, unsigned char val) { if (((x - iv->pos.x) < MAX_INVADER_WIDTH) && ((x - iv->pos.x) >= 0) && ((y - iv->pos.y) < MAX_INVADER_HEIGHT) && ((y - iv->pos.y) >= 0)) { iv->map[x - iv->pos.x][y - iv->pos.y] = val; } } void setGuardPixel(unsigned char *guards, unsigned char x, unsigned char y, unsigned char val) { assert(val <= NUMPLANE); if (x < NUM_COLS && y == GUARD_LINE) { guards[x] = val; } } /*----------------------drawing Method---------------------------*/ void draw(offScreen_t offScreen, Invaders * iv, Spaceship * sc, Player * pl, Cannon * cn, unsigned char *guards, pixel *st, pixel * shot) { unsigned char x, y; /*---SPACESHIP---*/ if (sc->pos < NUM_COLS) { setOffScreenPixel(offScreen, sc->pos, SPACESHIP_LINE, sc->lives); } if ((sc->pos > 0) && ((sc->pos - 1) < NUM_COLS)) { setOffScreenPixel(offScreen, sc->pos - 1, SPACESHIP_LINE, sc->lives); } /*---INVADERS--*/ for (y = MAX_INVADER_HEIGHT; y--;) { for (x = MAX_INVADER_WIDTH; x--;) { if ((x + iv->pos.x >= 0) && (x + iv->pos.x < NUM_COLS) && (y + iv->pos.y < NUM_ROWS)) { setOffScreenPixel(offScreen, x + iv->pos.x, y + iv->pos.y, iv->map[x][y]); } } } /*---GUARDS---*/ for (x = NUM_COLS; x--;) { setOffScreenPixel(offScreen, x, GUARD_LINE, guards[x]); } /*---SHOTS--*/ unsigned char i; for (i = MAX_SHOTS; i--;) { if (st[i].x < NUM_COLS && st[i].y < NUM_ROWS) { setOffScreenPixel(offScreen, st[i].x, st[i].y, 3); } } /*draw player shot*/ if (!(cn->ready)) { setOffScreenPixel(offScreen, shot->x, shot->y, 3); } /*-- CANNON --*/ if (cn->pos > 0) /* right border */ { setOffScreenPixel(offScreen, cn->pos - 1, NUM_ROWS - 1, pl->lives); } if (cn->pos < NUM_COLS) { setOffScreenPixel(offScreen, cn->pos, NUM_ROWS - 2, pl->lives); setOffScreenPixel(offScreen, cn->pos, NUM_ROWS - 1, pl->lives); } if (cn->pos < (NUM_COLS - 1)) /* left border */ { setOffScreenPixel(offScreen, cn->pos + 1, NUM_ROWS - 1, pl->lives); } flushOffScreenBuffer(offScreen); }