A implementation of a simple bomberman game
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player
Fork of rtos_basic by
myBMP.cpp
00001 #include "myBMP.h" 00002 00003 int BitDepth = 1; 00004 int Width = 1; 00005 int Height = 1; 00006 RGBApixel *Colors; 00007 00008 bool SafeFread( char* buffer, int size, int number, FILE* fp ) 00009 { 00010 using namespace std; 00011 int ItemsRead; 00012 if( feof(fp) ) 00013 { return false; } 00014 ItemsRead = (int) fread( buffer , size , number , fp ); 00015 if( ItemsRead < number ) 00016 { return false; } 00017 return true; 00018 } 00019 00020 bool Read32bitRow(int x, int y, ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd) 00021 { 00022 int i; 00023 char Colors[4]; 00024 if( Width*4 > BufferSize ) 00025 { return false; } 00026 for( i=0 ; i < Width ; i++ ) 00027 { 00028 memcpy( (char*) &(Colors), (char*) Buffer+4*i, 4 ); 00029 //Blue, Green, Red, Alpha 00030 int color = 0x00000000 | (Colors[2] << 16) | (Colors[1] << 8) | (Colors[0]); 00031 (*lcd).pixel(x+i,y+Row,color); 00032 } 00033 return true; 00034 } 00035 00036 bool Read24bitRow(int x, int y, ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd) 00037 { 00038 int i; 00039 char Colors[4]; 00040 if( Width*3 > BufferSize ) 00041 { return false; } 00042 for( i=0 ; i < Width ; i++ ) 00043 { 00044 memcpy( (char*) &(Colors), (char*) Buffer+3*i, 3 ); 00045 //Blue, Green, Red, Alpha 00046 int color = 0x00000000 | (Colors[2] << 16) | (Colors[1] << 8) | (Colors[0]); 00047 (*lcd).pixel(x+i,y+Row,color); 00048 } 00049 return true; 00050 } 00051 00052 RGBApixel GetColor( int ColorNumber) 00053 { 00054 RGBApixel Output; 00055 Output.Red = 255; 00056 Output.Green = 255; 00057 Output.Blue = 255; 00058 Output.Alpha = 0; 00059 00060 if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 ) 00061 { 00062 return Output; 00063 } 00064 if( !Colors ) 00065 { 00066 return Output; 00067 } 00068 Output = Colors[ColorNumber]; 00069 return Output; 00070 } 00071 00072 bool Read8bitRow(int x, int y, ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd) 00073 { 00074 int i; 00075 if( Width > BufferSize ) 00076 { return false; } 00077 for( i=0 ; i < Width ; i++ ) 00078 { 00079 int Index = Buffer[i]; 00080 //Blue, Green, Red, Alpha 00081 RGBApixel colors = GetColor(Index); 00082 int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); 00083 (*lcd).pixel(x+i,y+Row,color); 00084 } 00085 return true; 00086 } 00087 00088 bool Read4bitRow(int x, int y, ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd) 00089 { 00090 int Shifts[2] = {4 ,0 }; 00091 int Masks[2] = {240,15}; 00092 00093 int i=0; 00094 int j; 00095 int k=0; 00096 if( Width > 2*BufferSize ) 00097 { return false; } 00098 while( i < Width ) 00099 { 00100 j=0; 00101 while( j < 2 && i < Width ) 00102 { 00103 int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]); 00104 RGBApixel colors = GetColor(Index); 00105 int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); 00106 (*lcd).pixel(x+i,y+Row,color); 00107 i++; j++; 00108 } 00109 k++; 00110 } 00111 return true; 00112 } 00113 bool Read1bitRow(int x, int y, ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd) 00114 { 00115 int Shifts[8] = {7 ,6 ,5 ,4 ,3,2,1,0}; 00116 int Masks[8] = {128,64,32,16,8,4,2,1}; 00117 00118 int i=0; 00119 int j; 00120 int k=0; 00121 00122 if( Width > 8*BufferSize ) 00123 { return false; } 00124 while( i < Width ) 00125 { 00126 j=0; 00127 while( j < 8 && i < Width ) 00128 { 00129 int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]); 00130 RGBApixel colors = GetColor(Index); 00131 int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); 00132 (*lcd).pixel(x+i,y+Row,color); 00133 i++; j++; 00134 } 00135 k++; 00136 } 00137 return true; 00138 } 00139 00140 int TellNumberOfColors( int BitDepth ) 00141 { 00142 int output = 1 << BitDepth; 00143 if( BitDepth == 32 ) 00144 { output = 1 << 24; } 00145 return output; 00146 } 00147 00148 bool ReadBMPFromFile(int x, int y, const char* FileName, RGBApixel *Colors, uLCD_4DGL *lcd) 00149 { 00150 FILE* fp = fopen( FileName, "rb" ); 00151 if( fp == NULL ) 00152 { 00153 return false; 00154 } 00155 00156 // read the file header 00157 00158 BMFH bmfh; 00159 bool NotCorrupted = true; 00160 00161 NotCorrupted &= SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD), 1, fp); 00162 00163 bool IsBitmap = false; 00164 00165 if( bmfh.bfType == 19778 ) 00166 { IsBitmap = true; } 00167 00168 if( !IsBitmap ) 00169 { 00170 fclose( fp ); 00171 return false; 00172 } 00173 00174 NotCorrupted &= SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1, fp); 00175 NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1, fp); 00176 NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1, fp); 00177 NotCorrupted &= SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp); 00178 00179 // read the info header 00180 00181 BMIH bmih; 00182 00183 NotCorrupted &= SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp); 00184 NotCorrupted &= SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp); 00185 NotCorrupted &= SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp); 00186 NotCorrupted &= SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1, fp); 00187 NotCorrupted &= SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1, fp); 00188 00189 NotCorrupted &= SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp); 00190 NotCorrupted &= SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp); 00191 NotCorrupted &= SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp); 00192 NotCorrupted &= SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp); 00193 NotCorrupted &= SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp); 00194 NotCorrupted &= SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp); 00195 00196 // a safety catch: if any of the header information didn't read properly, abort 00197 // future idea: check to see if at least most is self-consistent 00198 00199 if( !NotCorrupted ) 00200 { 00201 fclose(fp); 00202 return false; 00203 } 00204 00205 // if bmih.biCompression 1 or 2, then the file is RLE compressed 00206 00207 if( bmih.biCompression == 1 || bmih.biCompression == 2 ) 00208 { 00209 fclose(fp); 00210 return false; 00211 } 00212 00213 // if bmih.biCompression > 3, then something strange is going on 00214 // it's probably an OS2 bitmap file. 00215 00216 if( bmih.biCompression > 3 ) 00217 { 00218 fclose(fp); 00219 return false; 00220 } 00221 00222 if( bmih.biCompression == 3 && bmih.biBitCount != 16 ) 00223 { 00224 fclose(fp); 00225 return false; 00226 } 00227 00228 // set the bit depth 00229 00230 int TempBitDepth = (int) bmih.biBitCount; 00231 if( TempBitDepth != 1 && TempBitDepth != 4 00232 && TempBitDepth != 8 && TempBitDepth != 16 00233 && TempBitDepth != 24 && TempBitDepth != 32 ) 00234 { 00235 fclose(fp); 00236 return false; 00237 } 00238 BitDepth = (int)bmih.biBitCount; 00239 // set the size 00240 00241 if( (int) bmih.biWidth <= 0 || (int) bmih.biHeight <= 0 ) 00242 { 00243 fclose(fp); 00244 return false; 00245 } 00246 Width = (int) bmih.biWidth; 00247 Height = (int) bmih.biHeight; 00248 // some preliminaries 00249 00250 double dBytesPerPixel = ( (double) BitDepth ) / 8.0; 00251 double dBytesPerRow = dBytesPerPixel * (Width+0.0); 00252 dBytesPerRow = ceil(dBytesPerRow); 00253 00254 int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4; 00255 if( BytePaddingPerRow == 4 ) 00256 { BytePaddingPerRow = 0; } 00257 00258 // if < 16 bits, read the palette 00259 00260 if( BitDepth < 16 ) 00261 { 00262 // determine the number of colors specified in the 00263 // color table 00264 00265 int NumberOfColorsToRead = ((int) bmfh.bfOffBits - 54 )/4; 00266 if( NumberOfColorsToRead > (1 << BitDepth) ) 00267 { NumberOfColorsToRead = (1 << BitDepth); } 00268 00269 int n; 00270 for( n=0; n < NumberOfColorsToRead ; n++ ) 00271 { 00272 SafeFread( (char*) &(Colors[n]) , 4 , 1 , fp); 00273 } 00274 for( n=NumberOfColorsToRead ; n < TellNumberOfColors(BitDepth) ; n++ ) 00275 { 00276 RGBApixel wh; 00277 wh.Red = 255; 00278 wh.Green = 255; 00279 wh.Blue = 255; 00280 wh.Alpha = 0; 00281 Colors[n] = wh; 00282 } 00283 } 00284 00285 // skip blank data if bfOffBits so indicates 00286 00287 int BytesToSkip = bmfh.bfOffBits - 54;; 00288 if( BitDepth < 16 ) 00289 { BytesToSkip -= 4*(1 << BitDepth); } 00290 if( BitDepth == 16 && bmih.biCompression == 3 ) 00291 { BytesToSkip -= 3*4; } 00292 if( BytesToSkip < 0 ) 00293 { BytesToSkip = 0; } 00294 if( BytesToSkip > 0 && BitDepth != 16 ) 00295 { 00296 ebmpBYTE* TempSkipBYTE; 00297 TempSkipBYTE = new ebmpBYTE [BytesToSkip]; 00298 SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp); 00299 delete [] TempSkipBYTE; 00300 } 00301 00302 // This code reads 1, 4, 8, 24, and 32-bpp files 00303 // with a more-efficient buffered technique. 00304 00305 int i,j; 00306 if( BitDepth != 16 ) 00307 { 00308 int BufferSize = (int) ( (Width*BitDepth) / 8.0 ); 00309 while( 8*BufferSize < Width*BitDepth ) 00310 { BufferSize++; } 00311 while( BufferSize % 4 ) 00312 { BufferSize++; } 00313 ebmpBYTE* Buffer; 00314 Buffer = new ebmpBYTE [BufferSize]; 00315 j= Height-1; 00316 while( j > -1 ) 00317 { 00318 int BytesRead = (int) fread( (char*) Buffer, 1, BufferSize, fp ); 00319 if( BytesRead < BufferSize ) 00320 { 00321 j = -1; 00322 } 00323 else 00324 { 00325 bool Success = false; 00326 if( BitDepth == 1 ) 00327 { Success = Read1bitRow(x,y, Buffer, BufferSize, j , lcd); } 00328 if( BitDepth == 4 ) 00329 { Success = Read4bitRow(x,y, Buffer, BufferSize, j , lcd); } 00330 if( BitDepth == 8 ) 00331 { Success = Read8bitRow(x,y, Buffer, BufferSize, j , lcd); } 00332 if( BitDepth == 24 ) 00333 { Success = Read24bitRow(x,y, Buffer, BufferSize, j , lcd); } 00334 if( BitDepth == 32 ) 00335 { Success = Read32bitRow(x,y, Buffer, BufferSize, j , lcd); } 00336 if( !Success ) 00337 { 00338 j = -1; 00339 } 00340 } 00341 j--; 00342 } 00343 delete [] Buffer; 00344 } 00345 00346 if( BitDepth == 16 ) 00347 { 00348 int DataBytes = Width*2; 00349 int PaddingBytes = ( 4 - DataBytes % 4 ) % 4; 00350 00351 // set the default mask 00352 00353 ebmpWORD BlueMask = 31; // bits 12-16 00354 ebmpWORD GreenMask = 992; // bits 7-11 00355 ebmpWORD RedMask = 31744; // bits 2-6 00356 00357 // read the bit fields, if necessary, to 00358 // override the default 5-5-5 mask 00359 00360 if( bmih.biCompression != 0 ) 00361 { 00362 // read the three bit masks 00363 00364 ebmpWORD TempMaskWORD; 00365 00366 SafeFread( (char*) &RedMask , 2 , 1 , fp ); 00367 SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); 00368 00369 SafeFread( (char*) &GreenMask , 2 , 1 , fp ); 00370 SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); 00371 00372 SafeFread( (char*) &BlueMask , 2 , 1 , fp ); 00373 SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); 00374 } 00375 00376 // read and skip any meta data 00377 00378 if( BytesToSkip > 0 ) 00379 { 00380 ebmpBYTE* TempSkipBYTE; 00381 TempSkipBYTE = new ebmpBYTE [BytesToSkip]; 00382 SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp); 00383 delete [] TempSkipBYTE; 00384 } 00385 00386 // determine the red, green and blue shifts 00387 00388 int GreenShift = 0; 00389 ebmpWORD TempShiftWORD = GreenMask; 00390 while( TempShiftWORD > 31 ) 00391 { TempShiftWORD = TempShiftWORD>>1; GreenShift++; } 00392 int BlueShift = 0; 00393 TempShiftWORD = BlueMask; 00394 while( TempShiftWORD > 31 ) 00395 { TempShiftWORD = TempShiftWORD>>1; BlueShift++; } 00396 int RedShift = 0; 00397 TempShiftWORD = RedMask; 00398 while( TempShiftWORD > 31 ) 00399 { TempShiftWORD = TempShiftWORD>>1; RedShift++; } 00400 00401 // read the actual pixels 00402 00403 for( j=Height-1 ; j >= 0 ; j-- ) 00404 { 00405 i=0; 00406 int ReadNumber = 0; 00407 while( ReadNumber < DataBytes ) 00408 { 00409 ebmpWORD TempWORD; 00410 SafeFread( (char*) &TempWORD , 2 , 1 , fp ); 00411 ReadNumber += 2; 00412 00413 ebmpWORD Red = RedMask & TempWORD; 00414 ebmpWORD Green = GreenMask & TempWORD; 00415 ebmpWORD Blue = BlueMask & TempWORD; 00416 00417 ebmpBYTE BlueBYTE = (ebmpBYTE) 8*(Blue>>BlueShift); 00418 ebmpBYTE GreenBYTE = (ebmpBYTE) 8*(Green>>GreenShift); 00419 ebmpBYTE RedBYTE = (ebmpBYTE) 8*(Red>>RedShift); 00420 00421 int color = 0x00000000 | (RedBYTE << 16) | (GreenBYTE << 8) | (BlueBYTE); 00422 (*lcd).pixel(x+i,y+j,color); 00423 i++; 00424 } 00425 ReadNumber = 0; 00426 while( ReadNumber < PaddingBytes ) 00427 { 00428 ebmpBYTE TempBYTE; 00429 SafeFread( (char*) &TempBYTE , 1, 1, fp); 00430 ReadNumber++; 00431 } 00432 } 00433 00434 } 00435 00436 fclose(fp); 00437 return true; 00438 } 00439 00440 00441 BMIH::BMIH() 00442 { 00443 biPlanes = 1; 00444 biCompression = 0; 00445 biXPelsPerMeter = DefaultXPelsPerMeter; 00446 biYPelsPerMeter = DefaultYPelsPerMeter; 00447 biClrUsed = 0; 00448 biClrImportant = 0; 00449 } 00450 00451 BMFH::BMFH() 00452 { 00453 bfType = 19778; 00454 bfReserved1 = 0; 00455 bfReserved2 = 0; 00456 }
Generated on Thu Jul 14 2022 17:13:56 by 1.7.2