• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/cannonball/src/Gui.cpp

Go to the documentation of this file.
00001 #include "main.h"
00002 //#include "../header/Gui.h"
00003 
00004 Gui::Gui(IRender& render, IPhysic& physic, pMouseDevice mouse, const MouseMap& mouseMap)
00005 : m_render(render), m_physic(physic), m_mouse(mouse), m_mouseMap(mouseMap)
00006 {
00007         m_numControls = 0;
00008 }
00009 
00010 Gui::~Gui(void)
00011 {
00012 }
00013 
00014 void Gui::update()
00015 {
00016         if(m_render.guiIsShown()) {
00017                 if (m_mouse->isDown(m_mouseMap.mouseL)) {
00018                         int mouseX = m_mouse->getScreenX();
00019                         int mouseY = m_mouse->getScreenY();
00020                         for(int i = 0; i < m_numControls; i++) {
00021                                 m_controls[i]->hitTest(mouseX, mouseY);
00022                         }
00023                 }
00024         }
00025 }
00026 
00027 void Gui::addControl(pIControl control)
00028 {
00029         m_controls.push_back(control);
00030         m_numControls++;
00031 
00032         m_render.createGuiDrawCall(control);
00033 }
00034 
00035 void Gui::setGuiTexture(wchar* textureColor)
00036 {
00037         TextureData textureData;
00038 
00039         if(!loadTextureData(textureColor, textureColor, textureColor, textureData)) {
00040                 printf("Can't load texture data");
00041                 exit(0xff);
00042         }
00043 
00044         m_guiTexture = m_render.createTexture(textureData);
00045 }
00046 
00047 pIControl Gui::createLabel(float x, float y, float width, float height, int textureIndex)
00048 {
00049         
00050         //Create Meshdata
00051         MeshData meshData;
00052         float uvX1 = 1.0f, uvX2 = 1.0f;
00053         float uvY1 = 1.0f, uvY2 = 1.0f;
00054         if(textureIndex < 6) {
00055                 uvX1 = (float)(textureIndex % 2) * (256.0f / 512.0f);
00056                 uvX2 = uvX1 + (256.0f / 512.0f);
00057                 uvY1 = 1.0f - (float)(textureIndex / 2) * (128.0f / 512.0f);
00058                 uvY2 = uvY1 - (128.0f / 512.0f);
00059         } else if(textureIndex == 10) {
00060                 uvX1 = 16.0f / 512.0f;
00061                 uvX2 = 32.0f / 512.0f;
00062                 uvY1 = 1.0f - 3 * (128.0f / 512.0f);
00063                 uvY2 = uvY1 - (32.0f / 512.0f);
00064         } else if(textureIndex == 98) {
00065                 uvX1 = 0.0f;
00066                 uvX2 = 176.0f / 512.0f;
00067                 uvY1 = 1.0f - 3 * (128.0f / 512.0f) - (32.0f / 512.0f);
00068                 uvY2 = uvY1 - (32.0f / 512.0f);
00069         } else if(textureIndex == 99) {
00070                 uvX1 = 0.0f;
00071                 uvX2 = 15.0f / 512.0f;
00072                 uvY1 = 1.0f - 3 * (128.0f / 512.0f);
00073                 uvY2 = uvY1 - (31.0f / 512.0f);
00074         } else if(textureIndex == 100) {
00075                 uvX1 = 0.0f;
00076                 uvX2 = 80.0f / 512.0f;
00077                 uvY1 = 64.0f / 512.0f;
00078                 uvY2 = 32.0f / 512.0f;
00079         } else if(textureIndex == 101) {
00080                 uvX1 = 0.0f;
00081                 uvX2 = 96.0f / 512.0f;
00082                 uvY1 = 32.0f / 512.0f;
00083                 uvY2 = 0.0f;
00084         } else if(textureIndex = 102) {
00085                 uvX1 = 0.5;
00086                 uvX2 = 1.0f;
00087                 uvY1 = 64.0f / 512.0f;
00088                 uvY2 = 0.0f;
00089         } else if(textureIndex > 199) {
00090                 int iconIndex = textureIndex - 200;
00091                 uvX1 = 0.5 + ((float)(iconIndex % 4) * (64.0f / 512.0f));
00092                 uvX2 = uvX1 + 64.0f / 512.0f;
00093                 uvY1 = 0.5f - ((int)(iconIndex / 4)) * (64.0f / 512.0f);
00094                 uvY2 = uvY1 - 64.0f / 512.0f;
00095         }
00096 
00097         void* memory = malloc(sizeof(Vertex) * 4 + sizeof(ushort) * 6);
00098         Vertex* vertices = (Vertex*)memory;
00099         ushort* indices = (ushort*)&vertices[4];
00100 
00101         //upper left
00102         vertices[0].position[0] = x; vertices[0].position[1] =  y;
00103         vertices[0].position[2] = -1.0f; vertices[0].position[3] = 1.0f;
00104         vertices[0].color[0] = 0.0f; vertices[0].color[1] = 0.0f;
00105         vertices[0].color[2] = 0.0f; vertices[0].color[3] = 1.0f;
00106         vertices[0].uv[0] = uvX1; vertices[0].uv[1] = uvY1;
00107         vertices[0].uv[2] = 0.0f; vertices[0].uv[3] = 0.0f;
00108 
00109         //upper right
00110         vertices[1].position[0] = x + width; vertices[1].position[1] =  y;
00111         vertices[1].position[2] = -1.0f; vertices[1].position[3] = 1.0f;
00112         vertices[1].color[0] = 0.0f; vertices[1].color[1] = 0.0f;
00113         vertices[1].color[2] = 0.0f; vertices[1].color[3] = 1.0f;
00114         vertices[1].uv[0] = uvX2; vertices[1].uv[1] = uvY1;
00115         vertices[1].uv[2] = 0.0f; vertices[1].uv[3] = 0.0f;
00116 
00117         //lower right
00118         vertices[2].position[0] = x + width; vertices[2].position[1] =  y + height;
00119         vertices[2].position[2] = -1.0f; vertices[2].position[3] = 1.0f;
00120         vertices[2].color[0] = 0.0f; vertices[2].color[1] = 0.0f;
00121         vertices[2].color[2] = 0.0f; vertices[2].color[3] = 1.0f;
00122         vertices[2].uv[0] = uvX2; vertices[2].uv[1] = uvY2;
00123         vertices[2].uv[2] = 0.0f; vertices[2].uv[3] = 0.0f;
00124 
00125         //lower left
00126         vertices[3].position[0] = x; vertices[3].position[1] =  y + height;
00127         vertices[3].position[2] = -1.0f; vertices[3].position[3] = 1.0f;
00128         vertices[3].color[0] = 0.0f; vertices[3].color[1] = 0.0f;
00129         vertices[3].color[2] = 0.0f; vertices[3].color[3] = 1.0f;
00130         vertices[3].uv[0] = uvX1; vertices[3].uv[1] = uvY2;
00131         vertices[3].uv[2] = 0.0f; vertices[3].uv[3] = 0.0f;
00132 
00133         indices[0] = 0; indices[1] = 2; 
00134         indices[2] = 1; indices[3] = 0;
00135         indices[4] = 3; indices[5] = 2;
00136         
00137         meshData.vertexSize = sizeof(Vertex);
00138         meshData.vertexCount = 4;
00139         meshData.indexCount = 6;
00140         meshData.vertices = vertices;
00141         meshData.indices = indices;
00142 
00143         pIGeometry geometry = m_render.createGeometry(meshData);
00144 
00145         pIControl control = m_render.createControl(geometry, m_guiTexture);
00146         control->setX((int)x);
00147         control->setY((int)y);
00148         control->setWidth((int)width);
00149         control->setHeight((int)height);
00150 
00151         return control;
00152 
00153 }
00154 
00155 pIControl Gui::createButton(float x, float y, float width, float height, void callback(pIControl), int textureIndex)
00156 {
00157                 //Create Meshdata
00158         MeshData meshData;
00159         float uvX1 = 1.0f, uvX2 = 1.0f;
00160         float uvY1 = 1.0f, uvY2 = 1.0f;
00161                 if(textureIndex < 6) {
00162                 uvX1 = (float)(textureIndex % 2) * (256.0f / 512.0f);
00163                 uvX2 = uvX1 + (256.0f / 512.0f);
00164                 uvY1 = 1.0f - (float)(textureIndex / 2) * (128.0f / 512.0f);
00165                 uvY2 = uvY1 - (128.0f / 512.0f);
00166         }
00167 
00168         void* memory = malloc(sizeof(Vertex) * 4 + sizeof(ushort) * 6);
00169         Vertex* vertices = (Vertex*)memory;
00170         ushort* indices = (ushort*)&vertices[4];
00171 
00172         vertices[0].position[0] = x; vertices[0].position[1] =  y;
00173         vertices[0].position[2] = -1.0f; vertices[0].position[3] = 1.0f;
00174         vertices[0].color[0] = 0.0f; vertices[0].color[1] = 0.0f;
00175         vertices[0].color[2] = 0.0f; vertices[0].color[3] = 0.0f;
00176         vertices[0].uv[0] = uvX1; vertices[0].uv[1] = uvY1;
00177         vertices[0].uv[2] = 0.0f; vertices[0].uv[3] = 0.0f;
00178 
00179         vertices[1].position[0] = x + width; vertices[1].position[1] =  y;
00180         vertices[1].position[2] = -1.0f; vertices[1].position[3] = 1.0f;
00181         vertices[1].color[0] = 0.0f; vertices[1].color[1] = 0.0f;
00182         vertices[1].color[2] = 0.0f; vertices[1].color[3] = 0.0f;
00183         vertices[1].uv[0] = uvX2; vertices[1].uv[1] = uvY1;
00184         vertices[1].uv[2] = 0.0f; vertices[1].uv[3] = 0.0f;
00185 
00186         vertices[2].position[0] = x + width; vertices[2].position[1] =  y + height;
00187         vertices[2].position[2] = -1.0f; vertices[2].position[3] = 1.0f;
00188         vertices[2].color[0] = 0.0f; vertices[2].color[1] = 0.0f;
00189         vertices[2].color[2] = 0.0f; vertices[2].color[3] = 0.0f;
00190         vertices[2].uv[0] = uvX2; vertices[2].uv[1] = uvY2;
00191         vertices[2].uv[2] = 0.0f; vertices[2].uv[3] = 0.0f;
00192 
00193         vertices[3].position[0] = x; vertices[3].position[1] =  y + height;
00194         vertices[3].position[2] = -1.0f; vertices[3].position[3] = 1.0f;
00195         vertices[3].color[0] = 0.0f; vertices[3].color[1] = 0.0f;
00196         vertices[3].color[2] = 0.0f; vertices[3].color[3] = 0.0f;
00197         vertices[3].uv[0] = uvX1; vertices[3].uv[1] = uvY2;
00198         vertices[3].uv[2] = 0.0f; vertices[3].uv[3] = 0.0f;
00199 
00200         indices[0] = 0; indices[1] = 2; 
00201         indices[2] = 1; indices[3] = 0;
00202         indices[4] = 3; indices[5] = 2;
00203         
00204         meshData.vertexSize = sizeof(Vertex);
00205         meshData.vertexCount = 4;
00206         meshData.indexCount = 6;
00207         meshData.vertices = vertices;
00208         meshData.indices = indices;
00209 
00210         pIGeometry geometry = m_render.createGeometry(meshData);
00211 
00212         pIControl control = m_render.createButton(geometry, m_guiTexture, callback);
00213         control->setX((int)x);
00214         control->setY((int)y);
00215         control->setWidth((int)width);
00216         control->setHeight((int)height);
00217 
00218         return control;
00219 }
00220 
00221 void Gui::setUpStatusLabels()
00222 {
00223         for(int i = 0; i < 10; i++){
00224                 m_statusLabels[i] = createLabel(10,10, 64, 64, i + 200);
00225                 m_statusLabels[i]->setVisible(false);
00226                 m_statusLabels[i]->setName(TEXT("HUD"));
00227                 addControl(m_statusLabels[i]);
00228         }
00229 
00230         m_fpsLabel[0] = createLabel(112, 10, 16, 32, 10);
00231         m_fpsLabel[1] = createLabel(96, 10, 16, 32, 10);
00232         m_fpsLabel[2] = createLabel(80, 10, 16, 32, 10);
00233 
00234         for(int i = 0; i < 3; i++) {
00235                 m_fpsLabel[i]->setVisible(false);
00236                 m_fpsLabel[i]->setName(TEXT("HUD"));
00237                 addControl(m_fpsLabel[i]);
00238         }
00239 
00240         m_winnerLabel = createLabel(384, 362, 256, 64, 102);
00241         m_winnerLabel->setVisible(false);
00242         m_winnerLabel->setName(TEXT("HUD"));
00243         addControl(m_winnerLabel);
00244 }
00245 
00246 void Gui::showStatusLabel(int index)
00247 {
00248         for(int i = 0; i < 10; i++) {
00249                 if(i == index) m_statusLabels[i]->setVisible(true);
00250                 else m_statusLabels[i]->setVisible(false);
00251         }
00252 }
00253 
00254 void Gui::hideAllStatusLabels()
00255 {
00256         for(int i = 0; i < 10; i++) {
00257                 m_statusLabels[i]->setVisible(false);
00258         }
00259 }
00260 
00261 void Gui::showFPS()
00262 {
00263         for(int i = 0; i < 3; i++) { m_fpsLabel[i]->setVisible(true); }
00264 }
00265 
00266 void Gui::hideFPS() {
00267         for(int i = 0; i <3; i++) { m_fpsLabel[i]->setVisible(false);} 
00268 }
00269 
00270 void Gui::setFPSValue(int fps) 
00271 {
00272         for(int i = 0; i < 3; i++) {
00273                 m_fpsLabel[i]->setIndex(fps % 10);
00274                 fps /= 10;
00275         }
00276 }
00277 
00278 bool Gui::loadTextureData(const wchar* colorFilename, const wchar* normalFilename, const wchar* heightFilename, TextureData& out)
00279 {
00280         Pixel* colorData = 0;
00281         Pixel* normalData = 0;
00282         Pixel* heightData = 0;
00283         int widthColor = 0, heightColor = 0;
00284         int widthDetail = 0, heightDetail = 0;
00285         bool ok = true;
00286 
00287         ok = loadUnknown(colorFilename, widthColor, heightColor, 0);
00288         if(ok) ok = loadUnknown(colorFilename, widthColor, heightColor, &colorData);
00289         ok = loadUnknown(normalFilename, widthDetail, heightDetail, 0);
00290         if(ok) ok = loadUnknown(normalFilename, widthDetail, heightDetail, &normalData);
00291         if(ok) ok = loadUnknown(heightFilename, widthDetail, heightDetail, &heightData);
00292 
00293         if(ok == false)
00294         {
00295                 SAVEFREE(colorData);
00296                 SAVEFREE(normalData);
00297                 SAVEFREE(heightData);
00298                 return false;
00299         }
00300 
00301         int mipmapsColor = 0;
00302         int mipmapsDetail = 0;
00303         int mipmapPixelsColor = 0;
00304         int mipmapPixelsDetail = 0;
00305         MipMap* colorMipmaps;
00306         MipMap* detailMipmaps;
00307 
00308         for(int w=widthColor; w>0; mipmapPixelsColor+=w*w, w/=2, mipmapsColor++);
00309         for(int w=widthDetail; w>0; mipmapPixelsDetail+=w*w, w/=2, mipmapsDetail++);
00310 
00311         void* mem = malloc(sizeof(MipMap)*(mipmapsColor+mipmapsDetail) + sizeof(Pixel)*(mipmapPixelsColor+mipmapPixelsDetail));
00312 
00313         colorMipmaps = (MipMap*)mem;
00314         detailMipmaps = &colorMipmaps[mipmapsColor];
00315         Pixel* colorPixels = (Pixel*)&detailMipmaps[mipmapsDetail];
00316         Pixel* detailPixels = &colorPixels[mipmapPixelsColor];
00317 
00318         for(int i=0, w=widthColor, curPixel=0; i<mipmapsColor; curPixel+=w*w, w/=2, i++)
00319         {
00320                 colorMipmaps[i].width = w;
00321                 colorMipmaps[i].height = w;
00322                 colorMipmaps[i].data = &colorPixels[curPixel];
00323         }
00324 
00325         for(int i=0, w=widthDetail, curPixel=0; i<mipmapsDetail; curPixel+=w*w, w/=2, i++)
00326         {
00327                 detailMipmaps[i].width = w;
00328                 detailMipmaps[i].height = w;
00329                 detailMipmaps[i].data = &detailPixels[curPixel];
00330         }
00331 
00332         // copy loaded data
00333         for(int y=0; y<colorMipmaps[0].height; y++)
00334         {
00335                 for(int x=0; x<colorMipmaps[0].width; x++)
00336                         colorMipmaps[0].data[y*widthColor+x] = colorData[y*widthColor+x];
00337         }
00338 
00339         // compute color mipmaps
00340         for(int i=0; i<mipmapsColor-1; i++)
00341         {
00342                 for(int y=0; y<colorMipmaps[i+1].height; y++)
00343                 {
00344                         for(int x=0; x<colorMipmaps[i+1].width; x++)
00345                         {
00346                                 int color[4];
00347                                 for(int c=0; c<4; color[c]  = colorMipmaps[i].data[((y+0)* colorMipmaps[i].width + x + 0)*2].canal[c], c++);
00348                                 for(int c=0; c<4; color[c] += colorMipmaps[i].data[((y+0)* colorMipmaps[i].width + x + 1)*2].canal[c], c++);
00349                                 for(int c=0; c<4; color[c] += colorMipmaps[i].data[((y+1)* colorMipmaps[i].width + x + 0)*2].canal[c], c++);
00350                                 for(int c=0; c<4; color[c] += colorMipmaps[i].data[((y+1)* colorMipmaps[i].width + x + 1)*2].canal[c], c++);
00351                                 for(int c=0; c<4; colorMipmaps[i+1].data[y * colorMipmaps[i+1].width + x].canal[c] = uchar(color[c]/4), c++);
00352                         }
00353                 }
00354         }
00355 
00356         // copy loaded height data
00357         for(int y=0; y<detailMipmaps[0].height; y++)
00358         {
00359                 for(int x=0; x<detailMipmaps[0].width; x++)
00360                 {
00361                         normalData[y*widthDetail+x].a = heightData[y*widthDetail+x].r;
00362                         detailMipmaps[0].data[y*widthDetail+x] = normalData[y*widthDetail+x];
00363                 }
00364         }
00365 
00366         // compute color mipmaps
00367         for(int i=0; i<mipmapsDetail-1; i++)
00368         {
00369                 for(int y=0; y<detailMipmaps[i].height/2; y++)
00370                 {
00371                         for(int x=0; x<detailMipmaps[i].width/2; x++)
00372                         {
00373                                 int normal[4];
00374                                 for(int c=0; c<4; normal[c]  = detailMipmaps[i].data[((y+0)* detailMipmaps[i].width + x + 0)*2].canal[c], c++);
00375                                 for(int c=0; c<4; normal[c] += detailMipmaps[i].data[((y+0)* detailMipmaps[i].width + x + 1)*2].canal[c], c++);
00376                                 for(int c=0; c<4; normal[c] += detailMipmaps[i].data[((y+1)* detailMipmaps[i].width + x + 0)*2].canal[c], c++);
00377                                 for(int c=0; c<4; normal[c] += detailMipmaps[i].data[((y+1)* detailMipmaps[i].width + x + 1)*2].canal[c], c++);
00378                                 for(int c=0; c<4; detailMipmaps[i+1].data[y * detailMipmaps[i+1].width + x].canal[c] = uchar(normal[c]/4), c++);
00379                         }
00380                 }
00381         }
00382 
00383         // free temporary data
00384         SAVEFREE(colorData);
00385         SAVEFREE(normalData);
00386         SAVEFREE(heightData);
00387 
00388         // fill output structure
00389         out.mipmapsColor = mipmapsColor;
00390         out.mipmapsDetail = mipmapsDetail;
00391         out.color = colorMipmaps;
00392         out.detail = detailMipmaps;
00393         return true;
00394 }
00395 
00396 
00397 bool Gui::loadUnknown(const wchar* filename, int& width, int& height, Pixel** outData)
00398 {
00399         bool ok = true;
00400         size_t filenameLength = wcslen(filename);
00401 
00402         if(wcscmp(&filename[filenameLength-4], TEXT(".bmp")) == 0)
00403                 ok = loadBMP(filename, width, height, outData);
00404         //else if(wcscmp(&filename[filenameLength-4], TEXT(".tga")) == 0)
00405                 //ok = loadTGA(filename, width, height, outData);
00406         else
00407                 return false;
00408 
00409         if(outData == 0 && width != height)
00410                 return false;
00411 
00412         return ok;
00413 }
00414 
00415 struct BMP_SIGNATURE {
00416         BMP_SIGNATURE() {
00417                 this->c[0] = 'B';
00418                 this->c[1] = 'M';
00419         }
00420         union {
00421                 unsigned short int s;//= 'MB';
00422                 unsigned char c[2];
00423         };
00424 };
00425 
00426 const BMP_SIGNATURE bmpSignature;
00427 const unsigned short int BITMAP_SIGNATURE = bmpSignature.s;
00428 
00429 typedef struct {
00430         unsigned short int Signature;
00431         unsigned int Size;
00432         unsigned int Reserved;
00433         unsigned int BitsOffset;
00434 } BITMAP_FILEHEADER;
00435 
00436 #define BITMAP_FILEHEADER_SIZE 14
00437 
00438 typedef struct {
00439         unsigned int HeaderSize;
00440         int Width;
00441         int Height;
00442         unsigned short int Planes;
00443         unsigned short int BitCount;
00444         unsigned int Compression;
00445         unsigned int SizeImage;
00446         int PelsPerMeterX;
00447         int PelsPerMeterY;
00448         unsigned int ClrUsed;
00449         unsigned int ClrImportant;
00450         unsigned int RedMask;
00451         unsigned int GreenMask;
00452         unsigned int BlueMask;
00453         unsigned int AlphaMask;
00454         unsigned int CsType;
00455         unsigned int Endpoints[9]; // see http://msdn2.microsoft.com/en-us/library/ms536569.aspx
00456         unsigned int GammaRed;
00457         unsigned int GammaGreen;
00458         unsigned int GammaBlue;
00459 } BITMAP_HEADER;
00460 
00461 typedef struct {
00462         unsigned char Red;
00463         unsigned char Green;
00464         unsigned char Blue;
00465         unsigned char Alpha;
00466 } RGBA;
00467 
00468 typedef struct {
00469         unsigned char Blue;
00470         unsigned char Green;
00471         unsigned char Red;
00472         unsigned char Alpha;
00473 } BGRA;
00474 
00475 typedef struct {
00476         unsigned char Blue;
00477         unsigned char Green;
00478         unsigned char Red;
00479 } BGR;
00480 
00481 typedef struct {
00482         unsigned short int Blue:5;
00483         unsigned short int Green:5;
00484         unsigned short int Red:5;
00485         unsigned short int Reserved:1;
00486 } BGR16;
00487 
00488 uint Gui::ShiftRightByMask(uint Color, uint Mask, uint DistributeToBits ) {
00489         if (Mask == 0) return 0;
00490 
00491         uint ShiftCount = 0;
00492         uint Test = 0x00000001;
00493 
00494         while((ShiftCount<32) && !(Mask & Test)){
00495                 Test <<= 1;
00496                 ShiftCount++;
00497         }
00498         
00499         uint BitCount = 32;
00500         Test = 0x80000000;
00501 
00502         while(BitCount && !((Mask >> ShiftCount) & Test)){
00503                 Test >>= 1;
00504                 BitCount--;
00505         }
00506 
00507         uint BaseColor = (Color & Mask) >> ShiftCount;
00508 
00509         if(DistributeToBits > BitCount){
00510                 /* We have to fill lower bits */
00511                 uint BitsToFill = DistributeToBits - BitCount;
00512                 while(BitsToFill--) {
00513                         BaseColor <<= 1;
00514                         if(BaseColor & 1)
00515                                 BaseColor |= 1;
00516                 }
00517         }else if(DistributeToBits < BitCount){
00518                 BaseColor >>= (BitCount - DistributeToBits);
00519         }
00520         return BaseColor;
00521 }
00522 
00523 bool Gui::loadBMP(const wchar* filename, int& width, int& height, Pixel** outData){
00524         FILE* file = 0;
00525         BITMAP_FILEHEADER m_BitmapFileHeader;
00526         BITMAP_HEADER m_BitmapHeader;
00527         RGBA* m_BitmapData = 0;
00528         uchar *Line = 0;
00529         uint m_BitmapSize = 0;
00530         BGRA m_ColorTable[256];
00531         uint m_ColorTableSize = 0;
00532         int bmpWidth = 0, bmpHeight = 0;
00533 
00534         #define SAVEEXIT(rs) {\
00535                 if(file){fclose(file);file=0;}\
00536                 SAVEFREE(m_BitmapData);\
00537                 SAVEFREE(Line);\
00538                 return rs;}
00539  
00540         if(_wfopen_s(&file, filename, TEXT("rb")) != 0)
00541                 return false;
00542         
00543         fread(&m_BitmapFileHeader, BITMAP_FILEHEADER_SIZE, 1, file);
00544         if(m_BitmapFileHeader.Signature != BITMAP_SIGNATURE)
00545                 return false;
00546 
00547         fread(&m_BitmapHeader, sizeof(BITMAP_HEADER), 1, file);
00548         
00549         /* Load Color Table */
00550         fseek(file, BITMAP_FILEHEADER_SIZE + m_BitmapHeader.HeaderSize, SEEK_SET);
00551         
00552         switch(m_BitmapHeader.BitCount){
00553                 case 1: m_ColorTableSize = 2; break;
00554                 case 4: m_ColorTableSize = 16; break;
00555                 case 8: m_ColorTableSize = 256; break;
00556                 default: break;
00557         }
00558         
00559         if(m_ColorTableSize>0)
00560                 fread(m_ColorTable, sizeof(BGRA), m_ColorTableSize, file);
00561 
00562         /* ... Color Table for 16 or 32 Bit Images are not supported yet */     
00563         bmpWidth = m_BitmapHeader.Width < 0 ? -m_BitmapHeader.Width : m_BitmapHeader.Width;
00564         bmpHeight = m_BitmapHeader.Height < 0 ? -m_BitmapHeader.Height : m_BitmapHeader.Height;
00565 
00566         if(width > 0 && height > 0 && width != bmpWidth && height != bmpHeight){
00567                 fclose(file);
00568                 return false;
00569         }
00570 
00571         width = bmpWidth;
00572         height = bmpHeight;
00573 
00574         if(outData == 0){
00575                 fclose(file);
00576                 return true;
00577         }
00578 
00579         m_BitmapSize = bmpWidth * bmpHeight;
00580         m_BitmapData = (RGBA*)malloc(sizeof(RGBA)*m_BitmapSize);
00581         
00582         uint LineWidth = (bmpWidth * m_BitmapHeader.BitCount/8 + 3) & ~3;
00583         Line = (uchar*)malloc(sizeof(uchar)*LineWidth);
00584         
00585         fseek(file, m_BitmapFileHeader.BitsOffset, SEEK_SET);
00586         
00587         int Index = 0;
00588         
00589         switch(m_BitmapHeader.Compression){
00590                 // no compression
00591                 case 0:{
00592                         for (int i = 0; i < bmpHeight; i++) {
00593                                 fread(Line, LineWidth, 1, file);
00594                                 uchar *LinePtr = Line;
00595 
00596                                 switch(m_BitmapHeader.BitCount) {
00597                                         case 1:
00598                                                 for(int j = 0; j < bmpWidth; j++){
00599                                                         uint Color = *((uchar*) LinePtr);
00600                                                         for (int k = 0; k < 8; k++) {
00601                                                                 m_BitmapData[Index].Red   = m_ColorTable[Color & 0x80 ? 1 : 0].Red;
00602                                                                 m_BitmapData[Index].Green = m_ColorTable[Color & 0x80 ? 1 : 0].Green;
00603                                                                 m_BitmapData[Index].Blue  = m_ColorTable[Color & 0x80 ? 1 : 0].Blue;
00604                                                                 m_BitmapData[Index].Alpha = m_ColorTable[Color & 0x80 ? 1 : 0].Alpha;
00605                                                                 Index++;
00606                                                                 Color <<= 1;
00607                                                         }
00608                                                         LinePtr++;
00609                                                         j += 7;
00610                                                 }
00611                                                 break;
00612                                         case 4:
00613                                                 for(int j = 0; j < bmpWidth; j++){
00614                                                         uint Color = *((uchar*) LinePtr);
00615                                                         m_BitmapData[Index].Red   = m_ColorTable[(Color >> 4) & 0x0f].Red;
00616                                                         m_BitmapData[Index].Green = m_ColorTable[(Color >> 4) & 0x0f].Green;
00617                                                         m_BitmapData[Index].Blue  = m_ColorTable[(Color >> 4) & 0x0f].Blue;
00618                                                         m_BitmapData[Index].Alpha = m_ColorTable[(Color >> 4) & 0x0f].Alpha;
00619                                                         Index++;
00620                                                         m_BitmapData[Index].Red   = m_ColorTable[Color & 0x0f].Red;
00621                                                         m_BitmapData[Index].Green = m_ColorTable[Color & 0x0f].Green;
00622                                                         m_BitmapData[Index].Blue  = m_ColorTable[Color & 0x0f].Blue;
00623                                                         m_BitmapData[Index].Alpha = m_ColorTable[Color & 0x0f].Alpha;
00624                                                         Index++;
00625                                                         LinePtr++;
00626                                                         j++;
00627                                                 }
00628                                                 break;
00629                                         case 8:
00630                                                 for(int j = 0; j < bmpWidth; j++){
00631                                                         uint Color = *((uchar*) LinePtr);
00632                                                         m_BitmapData[Index].Red   = m_ColorTable[Color].Red;
00633                                                         m_BitmapData[Index].Green = m_ColorTable[Color].Green;
00634                                                         m_BitmapData[Index].Blue  = m_ColorTable[Color].Blue;
00635                                                         m_BitmapData[Index].Alpha = m_ColorTable[Color].Alpha;
00636                                                         Index++;
00637                                                         LinePtr++;
00638                                                 }
00639                                                 break;
00640                                         case 16:
00641                                                 for(int j = 0; j < bmpWidth; j++){
00642                                                         uint Color = *((unsigned short int*) LinePtr);
00643                                                         m_BitmapData[Index].Red   = ((Color >> 10) & 0x1f) << 3;
00644                                                         m_BitmapData[Index].Green = ((Color >> 5) & 0x1f) << 3;
00645                                                         m_BitmapData[Index].Blue  = (Color & 0x1f) << 3;
00646                                                         m_BitmapData[Index].Alpha = 255;
00647                                                         Index++;
00648                                                         LinePtr += 2;
00649                                                 }
00650                                                 break;
00651                                         case 24:
00652                                                 for(int j = 0; j < bmpWidth; j++){
00653                                                         uint Color = *((uint*) LinePtr);
00654                                                         m_BitmapData[Index].Blue  = Color & 0xff;
00655                                                         m_BitmapData[Index].Green = (Color >> 8) & 0xff;
00656                                                         m_BitmapData[Index].Red   = (Color >> 16) & 0xff;
00657                                                         m_BitmapData[Index].Alpha = 255;
00658                                                         Index++;
00659                                                         LinePtr += 3;
00660                                                 }
00661                                                 break;
00662                                         case 32:
00663                                                 for(int j = 0; j < bmpWidth; j++){
00664                                                         uint Color = *((uint*) LinePtr);
00665                                                         m_BitmapData[Index].Blue  = Color & 0xff;
00666                                                         m_BitmapData[Index].Green = (Color >> 8) & 0xff;
00667                                                         m_BitmapData[Index].Red   = (Color >> 16) & 0xff;
00668                                                         m_BitmapData[Index].Alpha = Color >> 24;
00669                                                         Index++;
00670                                                         LinePtr += 4;
00671                                                 }
00672                                                 break;
00673                                         default:
00674                                                 SAVEEXIT(false);
00675                                 }
00676                         }
00677                         break;
00678                 }
00679                 // RLE 8
00680                 case 1:{
00681                         uchar Count = 0;
00682                         uchar ColorIndex = 0;
00683                         int x = 0, y = 0;
00684 
00685                         for(bool run = true; !feof(file) && run; ){
00686                                 fread(&Count, 1, 1, file);
00687                                 fread(&ColorIndex, 1, 1, file);
00688 
00689                                 if (Count > 0) {
00690                                         Index = x + y * bmpWidth;
00691                                         for (int k = 0; k < Count; k++) {
00692                                                 m_BitmapData[Index + k].Red   = m_ColorTable[ColorIndex].Red;
00693                                                 m_BitmapData[Index + k].Green = m_ColorTable[ColorIndex].Green;
00694                                                 m_BitmapData[Index + k].Blue  = m_ColorTable[ColorIndex].Blue;
00695                                                 m_BitmapData[Index + k].Alpha = m_ColorTable[ColorIndex].Alpha;
00696                                         }
00697                                         x += Count;
00698                                 } else if (Count == 0) {
00699                                         int Flag = ColorIndex;
00700                                         switch(Flag){
00701                                                 case 0: x = 0; y++; break;
00702                                                 case 1: run = false; break;
00703                                                 case 2:{
00704                                                         char rx = 0;
00705                                                         char ry = 0;
00706                                                         fread(&rx, 1, 1, file);
00707                                                         fread(&ry, 1, 1, file);
00708                                                         x += rx;
00709                                                         y += ry;
00710                                                         break;
00711                                                 }
00712                                                 default:{
00713                                                         Count = Flag;
00714                                                         Index = x + y * bmpWidth;
00715                                                         for(int k = 0; k < Count; k++){
00716                                                                 fread(&ColorIndex, 1, 1, file);
00717                                                                 m_BitmapData[Index + k].Red   = m_ColorTable[ColorIndex].Red;
00718                                                                 m_BitmapData[Index + k].Green = m_ColorTable[ColorIndex].Green;
00719                                                                 m_BitmapData[Index + k].Blue  = m_ColorTable[ColorIndex].Blue;
00720                                                                 m_BitmapData[Index + k].Alpha = m_ColorTable[ColorIndex].Alpha;
00721                                                         }
00722                                                         x += Count;
00723                                                         if (ftell(file) & 1) fseek(file, 1, SEEK_CUR);
00724                                                         break;
00725                                                 }
00726                                         }
00727                                 }
00728                         }
00729                         break;
00730                 }
00731                 //case 2: // RLE 4 /* RLE 4 is not supported */
00732 
00733                 // BITFIELDS
00734                 case 3:{
00735                         /* We assumes that mask of each color component can be in any order */
00736                         for(int i=0; i<bmpHeight; i++){
00737                                 fread(Line, LineWidth, 1, file);
00738                                 uchar *LinePtr = Line;
00739                                 
00740                                 for(int j=0; j < bmpWidth; j++){
00741                                         uint Color = 0;
00742 
00743                                         if (m_BitmapHeader.BitCount == 16) {
00744                                                 Color = *((unsigned short int*) LinePtr);
00745                                                 LinePtr += 2;
00746                                         } else if (m_BitmapHeader.BitCount == 32) {
00747                                                 Color = *((uint*) LinePtr);
00748                                                 LinePtr += 4;
00749                                         }
00750                                         m_BitmapData[Index].Red   = ShiftRightByMask(Color, m_BitmapHeader.RedMask);
00751                                         m_BitmapData[Index].Green = ShiftRightByMask(Color, m_BitmapHeader.GreenMask);
00752                                         m_BitmapData[Index].Blue  = ShiftRightByMask(Color, m_BitmapHeader.BlueMask);
00753                                         m_BitmapData[Index].Alpha = ShiftRightByMask(Color, m_BitmapHeader.AlphaMask);
00754 
00755                                         Index++;
00756                                 }
00757                         }
00758                         break;
00759                 }
00760                 default:
00761                         SAVEEXIT(false);
00762         }
00763 
00764         SAVEFREE(Line);
00765         fclose(file);
00766 
00767         *outData = (Pixel*)m_BitmapData;
00768         return true;
00769         #undef SAVEEXIT
00770 }

Generated on Fri Jun 18 2010 17:48:39 for Cannonball by  doxygen 1.7.0