Platform_Win32_Screen_GDI.cpp
Go to the documentation of this file.00001 //*** Platform_Win32_Screen_GDI.cpp *** 00002 00003 #include "Platform_Win32_Screen_GDI.h" 00004 00005 #define WIN32_LEAN_AND_MEAN 00006 #define VC_EXTRALEAN 00007 #include <windows.h> 00008 00009 00010 //*** Constructor *** 00011 00012 Platform_Win32_Screen_GDI::Platform_Win32_Screen_GDI(struct HWND__* windowHandle, bool fullscreen, int screenWidth, int screenHeight): 00013 windowHandle_(windowHandle), 00014 fullscreen_(fullscreen), 00015 screenWidth_(screenWidth), 00016 screenHeight_(screenHeight), 00017 backBuffer_(0) 00018 { 00019 } 00020 00021 00022 //*** Setup *** 00023 00024 bool Platform_Win32_Screen_GDI::Setup() 00025 { 00026 if (fullscreen_) 00027 { 00028 SetWindowLong(windowHandle_,GWL_STYLE,WS_POPUP|WS_VISIBLE); 00029 00030 MoveWindow(windowHandle_,0,0,screenWidth_,screenHeight_,TRUE); 00031 } 00032 00033 if (fullscreen_) 00034 { 00035 RECT client; 00036 GetClientRect(GetDesktopWindow(),&client); 00037 screenWidth_=client.right-client.left; 00038 screenHeight_=client.bottom-client.top; 00039 } 00040 00041 HDC dc = GetDC(windowHandle_); 00042 BitBlt(dc,0,0,screenWidth_,screenHeight_,0,0,0,BLACKNESS); 00043 ReleaseDC (windowHandle_, dc); 00044 00045 backBuffer_=new unsigned short[screenWidth_*screenHeight_]; 00046 return true; 00047 } 00048 00049 00050 //*** Destructor *** 00051 00052 Platform_Win32_Screen_GDI::~Platform_Win32_Screen_GDI() 00053 { 00054 if (backBuffer_) 00055 { 00056 delete[] backBuffer_; 00057 } 00058 if (fullscreen_) 00059 { 00060 SetWindowLong(windowHandle_,GWL_STYLE,WS_OVERLAPPEDWINDOW | WS_VISIBLE ); 00061 } 00062 } 00063 00064 00065 //*** Present *** 00066 00067 bool Platform_Win32_Screen_GDI::Present(unsigned short* bitmapData, int bitmapWidth, int bitmapHeight, unsigned short modulate, unsigned short backgroundColor) 00068 { 00069 lastPresentWidth_=bitmapWidth; 00070 lastPresentHeight_=bitmapHeight; 00071 00072 int dx=screenWidth_-bitmapWidth; 00073 int dy=screenHeight_-bitmapHeight; 00074 int scaleX=screenWidth_/bitmapWidth; 00075 int scaleY=screenHeight_/bitmapHeight; 00076 int scale=min(scaleX,scaleY); 00077 00078 // Straight copy 00079 if (dx==0 && dy==0) 00080 { 00081 if (modulate==0xffff) 00082 { 00083 SetDIBits(bitmapData,bitmapWidth,bitmapHeight); 00084 } 00085 else 00086 { 00087 ModulateBitmap(bitmapData,bitmapWidth,bitmapHeight,modulate); 00088 SetDIBits(backBuffer_,bitmapWidth,bitmapHeight); 00089 } 00090 } 00091 00092 // Center bitmap 00093 else if (dx>=0 && dy>=0 && scale==1) 00094 { 00095 if (modulate==0xffff) 00096 { 00097 SetDIBits(bitmapData,bitmapWidth,bitmapHeight,dx/2,dy/2); 00098 } 00099 else 00100 { 00101 ModulateBitmap(bitmapData,bitmapWidth,bitmapHeight,modulate); 00102 SetDIBits(backBuffer_,bitmapWidth,bitmapHeight,dx/2,dy/2); 00103 } 00104 } 00105 00106 // Crop bitmap 00107 else if (dx<0 || dy<0) 00108 { 00109 if (modulate==0xffff) 00110 { 00111 CropBitmap(bitmapData,bitmapWidth,bitmapHeight); 00112 } 00113 else 00114 { 00115 ModulateAndCropBitmap(bitmapData,bitmapWidth,bitmapHeight,modulate); 00116 } 00117 SetDIBits(backBuffer_,min(screenWidth_,bitmapWidth),min(screenHeight_,bitmapHeight)); 00118 } 00119 00120 // Scale bitmap 00121 else 00122 { 00123 if (modulate==0xffff) 00124 { 00125 ScaleBitmap(bitmapData,bitmapWidth,bitmapHeight,scale); 00126 } 00127 else 00128 { 00129 ModulateAndScaleBitmap(bitmapData,bitmapWidth,bitmapHeight,modulate,scale); 00130 } 00131 SetDIBits(backBuffer_,bitmapWidth*scale,bitmapHeight*scale); 00132 } 00133 return true; 00134 } 00135 00136 00137 //*** ModulateBitmap *** 00138 00139 void Platform_Win32_Screen_GDI::ModulateBitmap(unsigned short* bitmapData, int bitmapWidth, int bitmapHeight, unsigned short modulate) 00140 { 00141 unsigned short* source=bitmapData; 00142 unsigned short* destination=backBuffer_; 00143 00144 int pixels=bitmapWidth*bitmapHeight; 00145 for (int i=0; i<pixels; i++) 00146 { 00147 *destination=RGBModulate16(*source,modulate); 00148 source++; 00149 destination++; 00150 } 00151 } 00152 00153 00154 //*** ScaleBitmap *** 00155 00156 void Platform_Win32_Screen_GDI::ScaleBitmap(unsigned short* bitmapData, int bitmapWidth, int bitmapHeight, int scale) 00157 { 00158 unsigned short* source=bitmapData; 00159 unsigned short* destination=backBuffer_; 00160 00161 int lineSize=bitmapWidth*scale; 00162 00163 for (int y=0; y<bitmapHeight; y++) 00164 { 00165 switch (scale) 00166 { 00167 case 2: 00168 { 00169 for (int x=0; x<bitmapWidth; x++) 00170 { 00171 unsigned short pixel=*source; 00172 source++; 00173 00174 unsigned int pixel32=pixel<<16 | pixel; 00175 00176 *reinterpret_cast<unsigned int*>(destination)=pixel32; 00177 destination+=2; 00178 } 00179 } break; 00180 case 3: 00181 { 00182 for (int x=0; x<bitmapWidth; x++) 00183 { 00184 unsigned short pixel=*source; 00185 source++; 00186 00187 unsigned int pixel32=pixel<<16 | pixel; 00188 00189 *reinterpret_cast<unsigned int*>(destination)=pixel32; 00190 destination+=2; 00191 *destination=pixel; 00192 destination++; 00193 } 00194 } break; 00195 case 4: 00196 { 00197 for (int x=0; x<bitmapWidth; x++) 00198 { 00199 unsigned short pixel=*source; 00200 source++; 00201 00202 unsigned int pixel32=pixel<<16 | pixel; 00203 00204 *reinterpret_cast<unsigned int*>(destination)=pixel32; 00205 destination+=2; 00206 *reinterpret_cast<unsigned int*>(destination)=pixel32; 00207 destination+=2; 00208 } 00209 } break; 00210 default: 00211 { 00212 for (int x=0; x<bitmapWidth; x++) 00213 { 00214 unsigned short pixel=*source; 00215 source++; 00216 for (int i=0; i<scale; i++) 00217 { 00218 *destination=pixel; 00219 destination++; 00220 } 00221 } 00222 } break; 00223 } 00224 00225 for (int i=1; i<scale; i++) 00226 { 00227 memcpy(destination,destination-lineSize,lineSize*sizeof(unsigned short)); 00228 destination+=lineSize; 00229 } 00230 } 00231 } 00232 00233 00234 //*** ModulateAndScaleBitmap *** 00235 00236 void Platform_Win32_Screen_GDI::ModulateAndScaleBitmap(unsigned short* bitmapData, int bitmapWidth, int bitmapHeight, unsigned short modulate, int scale) 00237 { 00238 unsigned short* source=bitmapData; 00239 unsigned short* destination=backBuffer_; 00240 00241 int lineSize=bitmapWidth*scale; 00242 00243 for (int y=0; y<bitmapHeight; y++) 00244 { 00245 switch (scale) 00246 { 00247 case 2: 00248 { 00249 for (int x=0; x<bitmapWidth; x++) 00250 { 00251 unsigned short pixel=RGBModulate16(*source,modulate); 00252 source++; 00253 00254 unsigned int pixel32=pixel<<16 | pixel; 00255 00256 *reinterpret_cast<unsigned int*>(destination)=pixel32; 00257 destination+=2; 00258 } 00259 } break; 00260 case 3: 00261 { 00262 for (int x=0; x<bitmapWidth; x++) 00263 { 00264 unsigned short pixel=RGBModulate16(*source,modulate); 00265 source++; 00266 00267 unsigned int pixel32=pixel<<16 | pixel; 00268 00269 *reinterpret_cast<unsigned int*>(destination)=pixel32; 00270 destination+=2; 00271 *destination=pixel; 00272 destination++; 00273 } 00274 } break; 00275 case 4: 00276 { 00277 for (int x=0; x<bitmapWidth; x++) 00278 { 00279 unsigned short pixel=RGBModulate16(*source,modulate); 00280 source++; 00281 00282 unsigned int pixel32=pixel<<16 | pixel; 00283 00284 *reinterpret_cast<unsigned int*>(destination)=pixel32; 00285 destination+=2; 00286 *reinterpret_cast<unsigned int*>(destination)=pixel32; 00287 destination+=2; 00288 } 00289 } break; 00290 default: 00291 { 00292 for (int x=0; x<bitmapWidth; x++) 00293 { 00294 unsigned short pixel=RGBModulate16(*source,modulate); 00295 source++; 00296 for (int i=0; i<scale; i++) 00297 { 00298 *destination=pixel; 00299 destination++; 00300 } 00301 } 00302 } break; 00303 } 00304 00305 for (int i=1; i<scale; i++) 00306 { 00307 memcpy(destination,destination-lineSize,lineSize*sizeof(unsigned short)); 00308 destination+=lineSize; 00309 } 00310 } 00311 } 00312 00313 00314 //*** CropBitmap *** 00315 00316 void Platform_Win32_Screen_GDI::CropBitmap(unsigned short* bitmapData, int bitmapWidth, int bitmapHeight ) 00317 { 00318 unsigned short* source=bitmapData; 00319 unsigned short* destination=backBuffer_; 00320 00321 int lineSize=min(screenWidth_,bitmapWidth)*sizeof(unsigned short); 00322 00323 int lines=min(screenHeight_,bitmapHeight); 00324 for (int y=0; y<lines; y++) 00325 { 00326 memcpy(destination,source,lineSize); 00327 source+=bitmapWidth; 00328 destination+=screenWidth_; 00329 } 00330 } 00331 00332 00333 //*** ModulateAndCropBitmap *** 00334 00335 void Platform_Win32_Screen_GDI::ModulateAndCropBitmap(unsigned short* bitmapData, int bitmapWidth, int bitmapHeight, unsigned short modulate) 00336 { 00337 unsigned short* source=bitmapData; 00338 unsigned short* destination=backBuffer_; 00339 00340 int width=min(screenWidth_,bitmapWidth); 00341 int sourceWidth=bitmapWidth-width; 00342 int destinationWidth=screenWidth_-width; 00343 00344 int lines=min(screenHeight_,bitmapHeight); 00345 for (int y=0; y<lines; y++) 00346 { 00347 for (int x=0; x<width; x++) 00348 { 00349 unsigned short pixel=RGBModulate16(*source,modulate); 00350 *destination=pixel; 00351 source++; 00352 destination++; 00353 } 00354 source+=sourceWidth; 00355 destination+=destinationWidth; 00356 } 00357 } 00358 00359 00360 //*** SetInterpolationMode *** 00361 00362 void Platform_Win32_Screen_GDI::SetInterpolationMode(bool enabled) 00363 { 00364 // Can't do interpolation mode with GDI 00365 } 00366 00367 00368 //*** SetDIBits *** 00369 00370 void Platform_Win32_Screen_GDI::SetDIBits(unsigned short* data, int width, int height, int x, int y) 00371 { 00372 HDC dc = GetDC(windowHandle_); 00373 00374 BITMAPV4HEADER bmi; 00375 memset (&bmi, 0, sizeof (bmi)); 00376 bmi.bV4Size = sizeof (BITMAPV4HEADER); 00377 bmi.bV4Width = width; 00378 bmi.bV4Height = -height; 00379 bmi.bV4Planes = 1; 00380 bmi.bV4V4Compression = BI_BITFIELDS; 00381 bmi.bV4XPelsPerMeter = 72; 00382 bmi.bV4YPelsPerMeter = 72; 00383 bmi.bV4BitCount = 16; 00384 bmi.bV4SizeImage = width*height*2; 00385 bmi.bV4RedMask = 31<<11; 00386 bmi.bV4GreenMask = 63<<5; 00387 bmi.bV4BlueMask = 31<<0; 00388 SetDIBitsToDevice(dc, x, y, width, height,0,0,0, height, data, reinterpret_cast<BITMAPINFO*>(&bmi), DIB_RGB_COLORS); 00389 00390 ReleaseDC (windowHandle_, dc); 00391 } 00392 00393 00394 //*** TransformCursorCoordinates *** 00395 00396 void Platform_Win32_Screen_GDI::TransformCursorCoordinates(float& x, float& y) 00397 { 00398 if (lastPresentWidth_==0 || lastPresentHeight_==0) 00399 { 00400 return; 00401 } 00402 00403 int hscale=screenWidth_/lastPresentWidth_; 00404 int vscale=screenHeight_/lastPresentHeight_; 00405 int pixelScale=max(1,min(hscale,vscale)); 00406 int hborder=max(0,(screenWidth_-pixelScale*lastPresentWidth_)/2); 00407 int vborder=max(0,(screenHeight_-pixelScale*lastPresentHeight_)/2); 00408 00409 x=(x-hborder)/pixelScale; 00410 y=(y-vborder)/pixelScale; 00411 }
Reproduction/republishing of any material on this site without permission is strictly prohibited.
