tanksprite.c

Go to the documentation of this file.
00001 
00024 #include "tanksprite.h"
00025 #include "color.h"
00026 #include <memory.h>
00027 
00032 #define FHoriz  1
00033 
00037 #define FVert   2
00038 
00042 #define Trans   4
00043 
00050 static const Uint8 spriteProtos[3][8] = {
00051     {   // up
00052         0x10, //{ 0, 0, 0, 0, 1, 0, 0, 0 },
00053         0x10, //{ 0, 0, 0, 0, 1, 0, 0, 0 },
00054         0xD6, //{ 0, 1, 1, 0, 1, 0, 1, 1 },
00055         0xFE, //{ 0, 1, 1, 1, 1, 1, 1, 1 },
00056         0xFE, //{ 0, 1, 1, 1, 1, 1, 1, 1 },
00057         0xFE, //{ 0, 1, 1, 1, 1, 1, 1, 1 },
00058         0xC6, //{ 0, 1, 1, 0, 0, 0, 1, 1 },
00059         0xC6  //{ 0, 1, 1, 0, 0, 0, 1, 1 }
00060     },
00061     {   // 22.5 to the right
00062         0x24, //{ 0, 0, 1, 0, 0, 1, 0, 0 },
00063         0x26, //{ 0, 1, 1, 0, 0, 1, 0, 0 },
00064         0x9E, //{ 0, 1, 1, 1, 1, 0, 0, 1 },
00065         0xFF, //{ 1, 1, 1, 1, 1, 1, 1, 1 },
00066         0xFF, //{ 1, 1, 1, 1, 1, 1, 1, 1 },
00067         0x72, //{ 0, 1, 0, 0, 1, 1, 1, 0 },
00068         0x70, //{ 0, 0, 0, 0, 1, 1, 1, 0 },
00069         0x20  //{ 0, 0, 0, 0, 0, 1, 0, 0 }
00070     },
00071     {   // 45 up right
00072         0x98, //{ 0, 0, 0, 1, 1, 0, 0, 1 },
00073         0x5C, //{ 0, 0, 1, 1, 1, 0, 1, 0 },
00074         0x3E, //{ 0, 1, 1, 1, 1, 1, 0, 0 },
00075         0xFF, //{ 1, 1, 1, 1, 1, 1, 1, 1 },
00076         0xFB, //{ 1, 1, 0, 1, 1, 1, 1, 1 },
00077         0x70, //{ 0, 0, 0, 0, 1, 1, 1, 0 },
00078         0x38, //{ 0, 0, 0, 1, 1, 1, 0, 0 },
00079         0x18  //{ 0, 0, 0, 1, 1, 0, 0, 0 }
00080     }
00081 };
00082 
00089 const static Uint8 imgFlags[16] = {
00090     0,
00091     0,
00092     0,
00093     FHoriz | FVert | Trans,
00094     FHoriz | Trans,
00095     FHoriz | Trans,
00096     FVert,
00097     FVert,
00098     FVert,
00099     FHoriz | FVert,
00100     FHoriz | FVert,
00101     Trans,
00102     Trans,
00103     FVert | Trans,
00104     FHoriz,
00105     FHoriz
00106 };
00107 
00108 Uint8 sprites[16][8];
00109 
00110 const Uint8 shellInitLoc[16][2] = {
00111     { 4, 0 }, // up
00112     { 5, 0 },
00113     { 7, 0 }, // up right
00114     { 7, 2 },
00115     { 7, 4 }, // right
00116     { 7, 5 },
00117     { 7, 7 }, // down right
00118     { 5, 7 },
00119     { 4, 7 }, // down
00120     { 2, 7 },
00121     { 0, 7 }, // down left
00122     { 0, 5 },
00123     { 0, 4 }, // left
00124     { 0, 2 },
00125     { 0, 0 }, // up left
00126     { 2, 0 }
00127 };
00128 
00129 void GenTankSprites() {
00130     int h, v, th, tv, t, img, rot;
00131     Uint8 flags;
00132     memset(sprites, 0, sizeof(sprites));
00133     for (rot = 0; rot < 16; rot++) {
00134         // get the flags to use
00135         flags = imgFlags[rot];
00136         // figure out which proto sprite to use
00137         if ((img = rot & 3) > 2) img = 1;
00138         // loop through each pixel of the sprite
00139         for (v = 0; v < 8; v++) {
00140             for (h = 0; h < 8; h++) {
00141                 // modify the coordinates to use base on the flags
00142                 if (flags & FHoriz) {
00143                     th = 7 - h;
00144                 }
00145                 else {
00146                     th = h;
00147                 }
00148                 if (flags & FVert) {
00149                     tv = 7 - v;
00150                 }
00151                 else {
00152                     tv = v;
00153                 }
00154                 if (flags & Trans) {
00155                     t = th;
00156                     th = tv;
00157                     tv = t;
00158                 }
00159                 if (spriteProtos[img][tv] & (1 << th)) {
00160                     sprites[rot][v] |= 1 << h;
00161                 }
00162             }
00163         }
00164     }
00165 }
00166 
00167 void DrawTank(SDL_Surface *dest, RenderItem *item) {
00168     SDL_Rect rect;
00169     int h, v, color = colorVals[((Player*)item)->team];
00170     Uint8 *sprite;
00171     Uint8 line;
00172     
00173     // get a pointer to the start of the sprite
00174     sprite = &(sprites[(((Player*)item)->rot >> 8) & 0xF][0]);
00175     // loop through each pixel of the sprite
00176     for (v = 0; v < 8; v++, sprite++) {
00177         // get the line data from the sprite
00178         line = *sprite;
00179         for (h = 0; h < 8; h++, line >>= 1) {
00180             // check pixels from left to right
00181             if (line & 1) {
00182                 // calclate screen position of the pixel
00183                 rect.x = item->physLocX + h * dInfo.luw;
00184                 rect.w = dInfo.luw;
00185                 rect.y = item->physLocY + v * dInfo.luh;
00186                 rect.h = dInfo.luh;
00187                 // draw it
00188                 SDL_FillRect(dest, &rect, color);
00189             }
00190         }
00191     }
00192 }
00193 
00194 Bool IsCollidingTank(Player *p1, Player *p2) {
00195     SDL_Rect p1rect, p2rect;
00196     int p1pos, p2pos, delta;
00197     Uint8 *p1sprite, *p2sprite;
00198     
00199     // Compute overlap region.
00200     // first, find the pixel coordinates by getting rid of the sub-pixel part
00201     p1pos = p1->y >> 8;
00202     p2pos = p2->y >> 8;
00203     if ((delta = p2pos - p1pos) > 0) {
00204         // check for no vertical overlap
00205         if (delta >= 8)
00206             return FALSE;
00207         // set y starting positions
00208         p1rect.y = delta;
00209         p2rect.y = 0;
00210     }
00211     else {
00212         // check for no vertical overlap
00213         if ((delta = -delta) >= 8)
00214             return FALSE;
00215         // set y starting positions
00216         p2rect.y = delta;
00217         p1rect.y = 0;
00218     }
00219     // store the height (same for p1 & p2)
00220     p1rect.h = 8 - delta;
00221     // see which is further left
00222     p1pos = p1->x >> 8;
00223     p2pos = p2->x >> 8;
00224     if ((delta = p2pos - p1pos) > 0) {
00225         // check for no horizontal overlap
00226         if (delta >= 8)
00227             return FALSE;
00228         // set x starting positions
00229         p1rect.x = delta;
00230         p2rect.x = 0;
00231     }
00232     else {
00233         // check for no horizontal overlap
00234         if ((delta = -delta) >= 8)
00235             return FALSE;
00236         // set x starting positions
00237         p2rect.x = delta;
00238         p1rect.x = 0;
00239     }
00240     // store the width (same for p1 & p2)
00241     //p1rect.w = 8 - delta;
00242     
00243     // check for an overlap of the sprites; do not include a 1 pixel boundry
00244     if ((delta >= 8) || ((Sint16)(p1rect.h) <= 0)) return FALSE;
00245     
00246     // compute the location of each player's sprite
00247     p1sprite = &(sprites[(p1->rot >> 8) & 0xF][p1rect.y]);
00248     p2sprite = &(sprites[(p2->rot >> 8) & 0xF][p2rect.y]);
00249     
00250     // loop through the overlapping height
00251     for (; p1rect.h > 0; p1rect.h--, p1sprite++, p2sprite++) {
00252         // check for a collision
00253         if (((*p1sprite) >> p1rect.x) & ((*p2sprite) >> p2rect.x)) return TRUE;
00254     }
00255     // no collision
00256     return FALSE;
00257 }
00258 
00259 Bool IsCollidingShell(Player *tank, Player *shell) {
00260     int x, y;
00261     // Compute where the shell is on the sprite.
00262     // First, compute the x coord on the sprite and check for no overlap
00263     if (((x = (shell->shellX >> 8) - (tank->x >> 8)) < 0) || (x >= 8)) {
00264         // no overlap so no collision
00265         return FALSE;
00266     }
00267     // next compute the y coord on the sprite and check for no overlap
00268     if (((y = (shell->shellY >> 8) - (tank->y >> 8)) < 0) || (y >= 8)) {
00269         // no overlap so no collision
00270         return FALSE;
00271     }
00272     // pixel check for collision
00273     if ((sprites[(tank->rot >> 8) & 0xF][y] >> x) & 1)
00274         return TRUE;
00275     return FALSE;
00276 }
00277 

Generated on Mon May 28 04:41:39 2007 for Retro Tank Super Attack by  doxygen 1.5.2