Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencardrgndraw.cppGo to the documentation of this file.00001 // 00002 // CardLib - CardRegion drawing support 00003 // 00004 // Freeware 00005 // Copyright J Brown 2001 00006 // 00007 #include <windows.h> 00008 #include <stdlib.h> 00009 #include "cardlib.h" 00010 #include "cardregion.h" 00011 #include "cardcolor.h" 00012 00013 HPALETTE UseNicePalette(HDC hdc, HPALETTE hPalette); 00014 void PaintRect(HDC hdc, RECT *rect, COLORREF colour); 00015 void CardBlt(HDC hdc, int x, int y, int nCardNum); 00016 void DrawCard(HDC hdc, int x, int y, HDC hdcSource, int width, int height); 00017 00018 // 00019 // Draw specified card at position x, y 00020 // xoff - source offset from left of card 00021 // yoff - source offset from top of card 00022 // width - width to draw 00023 // height - height to draw 00024 // 00025 void CardBlt(HDC hdc, int x, int y, int nCardNum)//, int xoff, int yoff, int width, int height) 00026 { 00027 int sx = nCardNum * __cardwidth; 00028 int sy = 0; 00029 int width = __cardwidth; 00030 int height = __cardheight; 00031 00032 //draw main center band 00033 BitBlt(hdc, x+2, y, width - 4, height, __hdcCardBitmaps, sx+2, sy+0, SRCCOPY); 00034 00035 //draw the two bits to the left 00036 BitBlt(hdc, x, y+2, 1, height - 4, __hdcCardBitmaps, sx+0, sy+2, SRCCOPY); 00037 BitBlt(hdc, x+1, y+1, 1, height - 2, __hdcCardBitmaps, sx+1, sy+1, SRCCOPY); 00038 00039 //draw the two bits to the right 00040 BitBlt(hdc, x+width-2, y+1, 1, height - 2, __hdcCardBitmaps, sx+width-2, sy+1, SRCCOPY); 00041 BitBlt(hdc, x+width-1, y+2, 1, height - 4, __hdcCardBitmaps, sx+width-1, sy+2, SRCCOPY); 00042 } 00043 00044 // 00045 // Draw a shape this this: 00046 // 00047 // ++++++++++++ 00048 // ++++++++++++++ 00049 // ++ ++ 00050 // 00051 void DrawHorzCardStrip(HDC hdc, int x, int y, int nCardNum, int height, BOOL fDrawTips) 00052 { 00053 int sx = nCardNum * __cardwidth; 00054 int sy = 0; 00055 int one = 1; 00056 int two = 2; 00057 BOOL tips = fDrawTips ? FALSE : TRUE; 00058 00059 if(height == 0) return; 00060 00061 if(height < 0) 00062 { 00063 sy = sy + __cardheight; 00064 y -= height; 00065 one = -one; 00066 two = -two; 00067 } 00068 00069 // draw the main vertical band 00070 // 00071 BitBlt(hdc, x + 2, y, __cardwidth - 4, height, __hdcCardBitmaps, sx+2, sy, SRCCOPY); 00072 00073 //if(height <= 1) return; 00074 00075 // draw the "lips" at the left and right 00076 BitBlt(hdc, x+1, y+one, 1, height-one*tips, __hdcCardBitmaps, sx+1, sy+one, SRCCOPY); 00077 BitBlt(hdc, x+__cardwidth-2, y+one, 1, height-one*tips, __hdcCardBitmaps, sx+__cardwidth-2, sy+one, SRCCOPY); 00078 00079 //if(height <= 2) return; 00080 00081 // draw the outer-most lips 00082 BitBlt(hdc, x, y+two, 1, height-two*tips, __hdcCardBitmaps, sx, sy+two, SRCCOPY); 00083 BitBlt(hdc, x+__cardwidth-1, y+two, 1, height-two*tips, __hdcCardBitmaps, sx+__cardwidth-1, sy+two, SRCCOPY); 00084 } 00085 00086 // 00087 // Draw a shape like this: 00088 // 00089 // +++ 00090 // +++ 00091 // +++ 00092 // +++ 00093 // +++ 00094 // +++ 00095 // +++ 00096 // +++ 00097 // +++ 00098 // +++ 00099 // 00100 // 00101 void DrawVertCardStrip(HDC hdc, int x, int y, int nCardNum, int width, BOOL fDrawTips) 00102 { 00103 int sx = nCardNum * __cardwidth; 00104 int sy = 0; 00105 int one = 1; 00106 int two = 2; 00107 BOOL tips = fDrawTips ? FALSE : TRUE; 00108 00109 if(width == 0) return; 00110 00111 00112 if(width < 0) 00113 { 00114 sx = sx + __cardwidth; 00115 x -= width; 00116 one = -1; 00117 two = -2; 00118 } 00119 00120 // draw the main vertical band 00121 // 00122 BitBlt(hdc, x, y + 2, width, __cardheight - 4, __hdcCardBitmaps, sx, sy+2, SRCCOPY); 00123 00124 //if(width <= 1) return; 00125 00126 // draw the "lips" at the top and bottom 00127 BitBlt(hdc, x+one, y+1, width-one*tips, 1, __hdcCardBitmaps, sx+one, sy + 1, SRCCOPY); 00128 BitBlt(hdc, x+one, y+__cardheight-2, width-one*tips, 1, __hdcCardBitmaps, sx+one, sy + __cardheight-2, SRCCOPY); 00129 00130 //if(width <= 2) return; 00131 00132 // draw the outer-most lips 00133 BitBlt(hdc, x+two, y, width-two*tips, 1, __hdcCardBitmaps, sx+two, sy, SRCCOPY); 00134 BitBlt(hdc, x+two, y+__cardheight-1, width-two*tips, 1, __hdcCardBitmaps, sx+two, sy + __cardheight-1, SRCCOPY); 00135 } 00136 00137 // 00138 // xdir - <0 or >0 00139 // ydir - <0 or >0 00140 // 00141 void DrawCardCorner(HDC hdc, int x, int y, int cardval, int xdir, int ydir) 00142 { 00143 int sx = cardval * __cardwidth; 00144 int sy = 0; 00145 00146 HDC hdcSource = __hdcCardBitmaps; 00147 00148 if(xdir < 0) 00149 { 00150 x += __cardwidth + xdir - 1; 00151 sx += __cardwidth + xdir - 1; 00152 } 00153 else 00154 { 00155 x += xdir; 00156 sx += xdir; 00157 } 00158 00159 if(ydir < 0) 00160 { 00161 y += __cardheight + ydir - 1; 00162 sy += __cardheight + ydir - 1; 00163 } 00164 else 00165 { 00166 y += ydir; 00167 sy += ydir; 00168 } 00169 00170 //convert x,y directions to -1, +1 00171 xdir = xdir < 0 ? -1 : 1; 00172 ydir = ydir < 0 ? -1 : 1; 00173 00174 SetPixel(hdc, x+xdir, y , GetPixel(hdcSource, sx+xdir, sy)); 00175 SetPixel(hdc, x, y, GetPixel(hdcSource, sx, sy)); 00176 SetPixel(hdc, x, y+ydir, GetPixel(hdcSource, sx, sy+ydir)); 00177 00178 } 00179 00180 // 00181 // Draw a card (i.e. miss out the corners) 00182 // 00183 void DrawCard(HDC hdc, int x, int y, HDC hdcDragCard, int width, int height) 00184 { 00185 //draw main center band 00186 BitBlt(hdc, x+2, y, width - 4, height, hdcDragCard, 2, 0, SRCCOPY); 00187 00188 //draw the two bits to the left 00189 BitBlt(hdc, x, y+2, 1, height - 4, hdcDragCard, 0, 2, SRCCOPY); 00190 BitBlt(hdc, x+1, y+1, 1, height - 2, hdcDragCard, 1, 1, SRCCOPY); 00191 00192 //draw the two bits to the right 00193 BitBlt(hdc, x+width-2, y+1, 1, height - 2, hdcDragCard, width-2, 1, SRCCOPY); 00194 BitBlt(hdc, x+width-1, y+2, 1, height - 4, hdcDragCard, width-1, 2, SRCCOPY); 00195 } 00196 00197 // 00198 // Clip a card SHAPE - basically any rectangle 00199 // with rounded corners 00200 // 00201 int ClipCard(HDC hdc, int x, int y, int width, int height) 00202 { 00203 ExcludeClipRect(hdc, x+2, y, x+2+width-4, y+ height); 00204 ExcludeClipRect(hdc, x, y+2, x+1, y+2+height-4); 00205 ExcludeClipRect(hdc, x+1, y+1, x+2, y+1+height-2); 00206 ExcludeClipRect(hdc, x+width-2, y+1, x+width-2+1, y+1+height-2); 00207 ExcludeClipRect(hdc, x+width-1, y+2, x+width-1+1, y+2+height-4); 00208 return 0; 00209 } 00210 00211 void CardRegion::Clip(HDC hdc) 00212 { 00213 int numtoclip; 00214 00215 if(fVisible == false) 00216 return; 00217 00218 Update(); //Update this stack's size+card count 00219 numtoclip = nNumApparentCards; 00220 00221 //if we are making this stack flash on/off, then only 00222 //clip the stack for drawing if the flash is in its ON state 00223 if(nFlashCount != 0) 00224 { 00225 if(fFlashVisible == FALSE) 00226 numtoclip = 0; 00227 } 00228 00229 //if offset along a diagonal 00230 if(xoffset != 0 && yoffset != 0 && cardstack.NumCards() != 0) 00231 { 00232 for(int j = 0; j < numtoclip; j ++) 00233 { 00234 ClipCard(hdc, xpos + xoffset * j, ypos + yoffset * j, __cardwidth, __cardheight); 00235 } 00236 } 00237 //otherwise if just offset along a horizontal/vertical axis 00238 else 00239 { 00240 if(yoffset < 0 && numtoclip > 0) 00241 { 00242 ClipCard(hdc, xpos, ypos-((numtoclip-1)*-yoffset), width, height); 00243 } 00244 else if(xoffset < 0 && numtoclip > 0) 00245 { 00246 ClipCard(hdc, xpos-((numtoclip-1)*-xoffset), ypos, width, height); 00247 } 00248 else 00249 { 00250 ClipCard(hdc, xpos, ypos, width, height); 00251 } 00252 } 00253 00254 } 00255 00256 void CardRegion::Render(HDC hdc) 00257 { 00258 int cardnum = 0; 00259 int numtodraw; 00260 BOOL fDrawTips; 00261 00262 Update(); //Update this stack's card count + size 00263 00264 numtodraw = nNumApparentCards; 00265 00266 if(nFlashCount != 0) 00267 { 00268 if(fFlashVisible == false) 00269 numtodraw = 0; 00270 } 00271 00272 if(fVisible == 0) return; 00273 00274 cardnum = cardstack.NumCards() - numtodraw; 00275 int counter; 00276 00277 for(counter = 0; counter < numtodraw; counter++) 00278 { 00279 int cardval; 00280 00281 int x = xoffset * counter + xpos; 00282 int y = yoffset * counter + ypos; 00283 00284 //if about to draw last card, then actually draw the top card 00285 if(counter == numtodraw - 1) cardnum = cardstack.NumCards() - 1; 00286 00287 Card card = cardstack.cardlist[cardnum]; 00288 cardval = card.Idx(); 00289 00290 if(card.FaceDown()) 00291 cardval = nBackCardIdx; //card-back 00292 00293 //only draw the visible part of the card 00294 if(counter < numtodraw - 1) 00295 { 00296 if(yoffset != 0 && xoffset != 0) 00297 fDrawTips = FALSE; 00298 else 00299 fDrawTips = TRUE; 00300 00301 if((yoffset != 0 && abs(xoffset) == 1) || (xoffset != 0 && abs(yoffset) == 1)) 00302 fDrawTips = TRUE; 00303 00304 //draw horizontal strips 00305 if(yoffset > 0) 00306 { 00307 DrawHorzCardStrip(hdc, x, y, cardval, yoffset, fDrawTips); 00308 } 00309 else if(yoffset < 0) 00310 { 00311 DrawHorzCardStrip(hdc, x, y+__cardheight+yoffset, cardval, yoffset, fDrawTips); 00312 } 00313 00314 //draw some vertical bars 00315 if(xoffset > 0) 00316 { 00317 DrawVertCardStrip(hdc, x, y, cardval, xoffset, fDrawTips); 00318 } 00319 else if(xoffset < 0) 00320 { 00321 DrawVertCardStrip(hdc, x+__cardwidth+xoffset, y, cardval, xoffset, fDrawTips); 00322 } 00323 00324 if(yoffset != 0 && xoffset != 0)//fDrawTips == FALSE) 00325 { 00326 //if we didn't draw any tips, then this is a 2-dim stack 00327 //(i.e, it goes at a diagonal). 00328 //in this case, we need to fill in the small triangle in 00329 //each corner! 00330 DrawCardCorner(hdc, x, y, cardval, xoffset, yoffset); 00331 } 00332 } 00333 //if the top card, draw the whole thing 00334 else 00335 { 00336 CardBlt(hdc, x, y, cardval); 00337 } 00338 00339 cardnum ++; 00340 00341 } //end of index 00342 00343 if(counter == 0) //if the cardstack is empty, then draw it that way 00344 { 00345 int x = xpos; 00346 int y = ypos; 00347 00348 switch(uEmptyImage) 00349 { 00350 default: 00351 case CS_EI_NONE: 00352 //this wipes the RECT variable, so watch out! 00353 //SetRect(&rect, x, y, x+__cardwidth, y+__cardheight); 00354 //PaintRect(hdc, &rect, MAKE_PALETTERGB(crBackgnd)); 00355 parentWnd.PaintCardRgn(hdc, x, y, __cardwidth, __cardheight, x, y); 00356 break; 00357 00358 case CS_EI_SUNK: 00359 DrawCard(hdc, x, y, __hdcPlaceHolder, __cardwidth, __cardheight); 00360 break; 00361 00362 case CS_EI_CIRC: 00363 case CS_EI_X: 00364 CardBlt(hdc, x, y, uEmptyImage); 00365 break; 00366 } 00367 00368 } 00369 00370 return; 00371 } 00372 00373 int calc_offset(int offset, int numcards, int numtodrag, int realvisible) 00374 { 00375 if(offset >= 0) 00376 return -offset * numcards; 00377 else 00378 return -offset * (numtodrag) + 00379 -offset * (realvisible - 1); 00380 } 00381 00382 void CardRegion::PrepareDragBitmaps(int numtodrag) 00383 { 00384 RECT rect; 00385 HDC hdc; 00386 int icard; 00387 int numcards = cardstack.NumCards(); 00388 int xoff, yoff; 00389 00390 if(nThreedCount > 1) 00391 { 00392 PrepareDragBitmapsThreed(numtodrag); 00393 return; 00394 } 00395 00396 //work out how big the bitmaps need to be 00397 nDragCardWidth = (numtodrag - 1) * abs(xoffset) + __cardwidth; 00398 nDragCardHeight = (numtodrag - 1) * abs(yoffset) + __cardheight; 00399 00400 //Create bitmap for the back-buffer 00401 hdc = GetDC(NULL); 00402 hdcBackGnd = CreateCompatibleDC(hdc); 00403 hbmBackGnd = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight); 00404 SelectObject(hdcBackGnd, hbmBackGnd); 00405 00406 //Create bitmap for the drag-image 00407 hdcDragCard = CreateCompatibleDC(hdc); 00408 hbmDragCard = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight); 00409 SelectObject(hdcDragCard, hbmDragCard); 00410 ReleaseDC(NULL, hdc); 00411 00412 UseNicePalette(hdcBackGnd, __hPalette); 00413 UseNicePalette(hdcDragCard, __hPalette); 00414 00415 int realvisible = numcards / nThreedCount; 00416 00417 //if(numcards > 0 && realvisible == 0) realvisible = 1; 00418 int iwhichcard = numcards - 1; 00419 if(nThreedCount == 1) iwhichcard = 0; 00420 00421 //grab the first bit of background so we can prep the back buffer; do this by 00422 //rendering the card stack (minus the card we are dragging) to the temporary 00423 //background buffer, so it appears if we have lifted the card from the stack 00424 //PaintRect(hdcBackGnd, &rect, crBackgnd); 00425 SetRect(&rect, 0, 0, nDragCardWidth, nDragCardHeight); 00426 00427 xoff = calc_offset(xoffset, numcards, numtodrag, realvisible); 00428 yoff = calc_offset(yoffset, numcards, numtodrag, realvisible); 00429 00430 parentWnd.PaintCardRgn(hdcBackGnd, 0, 0, nDragCardWidth, nDragCardHeight, xpos - xoff, ypos - yoff); 00431 00432 // 00433 // Render the cardstack into the back-buffer. The stack 00434 // has already had the dragcards removed, so just draw 00435 // what is left 00436 // 00437 for(icard = 0; icard < realvisible; icard++) 00438 { 00439 Card card = cardstack.cardlist[iwhichcard]; 00440 int nCardVal; 00441 00442 nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx; 00443 00444 xoff = xoffset * icard + calc_offset(xoffset, numcards, numtodrag, realvisible);//- xoffset * ((numcards+numtodrag) / nThreedCount - numtodrag); 00445 yoff = yoffset * icard + calc_offset(yoffset, numcards, numtodrag, realvisible);//- yoffset * ((numcards+numtodrag) / nThreedCount - numtodrag); 00446 00447 CardBlt(hdcBackGnd, xoff, yoff, nCardVal); 00448 iwhichcard++; 00449 } 00450 00451 // 00452 // If there are no cards under this one, just draw the place holder 00453 // 00454 if(numcards == 0) 00455 { 00456 int xoff = 0, yoff = 0; 00457 00458 if(xoffset < 0) xoff = nDragCardWidth - __cardwidth; 00459 if(yoffset < 0) yoff = nDragCardHeight - __cardheight; 00460 00461 switch(uEmptyImage) 00462 { 00463 case CS_EI_NONE: 00464 //No need to draw anything: We already cleared the 00465 //back-buffer before the main loop.. 00466 00467 //SetRect(&rc, xoff, yoff, xoff+ __cardwidth, yoff + __cardheight); 00468 //PaintRect(hdcBackGnd, &rc, MAKE_PALETTERGB(crBackgnd)); 00469 //parentWnd.PaintCardRgn(hdcBackGnd, xoff, yoff, __cardwidth, __cardheight, xpos, ypos);// + xoff, ypos + yoff); 00470 break; 00471 00472 case CS_EI_SUNK: 00473 DrawCard(hdcBackGnd, xoff, yoff, __hdcPlaceHolder, __cardwidth, __cardheight); 00474 break; 00475 00476 case CS_EI_CIRC: 00477 case CS_EI_X: 00478 CardBlt(hdc, xoff, yoff, uEmptyImage); 00479 break; 00480 } 00481 } 00482 00483 // 00484 // now render the drag-cards into the dragcard image 00485 // 00486 PaintRect(hdcDragCard, &rect, crBackgnd); 00487 00488 for(icard = 0; icard < numtodrag; icard++) 00489 { 00490 int nCardVal; 00491 00492 if(xoffset >= 0) xoff = xoffset * icard; 00493 else xoff = -xoffset * (numtodrag - icard - 1); 00494 00495 if(yoffset >= 0) yoff = yoffset * icard; 00496 else yoff = -yoffset * (numtodrag - icard - 1); 00497 00498 Card card = dragstack.cardlist[icard]; 00499 00500 nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx; 00501 00502 CardBlt(hdcDragCard, xoff, yoff, nCardVal); 00503 } 00504 } 00505 00506 void CardRegion::PrepareDragBitmapsThreed(int numtodrag) 00507 { 00508 RECT rect; 00509 HDC hdc; 00510 int icard; 00511 int numunder = 0; 00512 int iwhichcard; 00513 00514 int numcards = cardstack.NumCards(); 00515 00516 //work out how big the bitmaps need to be 00517 nDragCardWidth = (numtodrag - 1) * abs(xoffset) + __cardwidth; 00518 nDragCardHeight = (numtodrag - 1) * abs(yoffset) + __cardheight; 00519 00520 //Create bitmap for the back-buffer 00521 hdc = GetDC(NULL); 00522 hdcBackGnd = CreateCompatibleDC(hdc); 00523 hbmBackGnd = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight); 00524 SelectObject(hdcBackGnd, hbmBackGnd); 00525 00526 //create bitmap for the drag-image 00527 hdcDragCard = CreateCompatibleDC(hdc); 00528 hbmDragCard = CreateCompatibleBitmap(hdc, nDragCardWidth, nDragCardHeight); 00529 SelectObject(hdcDragCard, hbmDragCard); 00530 ReleaseDC(NULL, hdc); 00531 00532 UseNicePalette(hdcBackGnd, __hPalette); 00533 UseNicePalette(hdcDragCard, __hPalette); 00534 00535 //grab the first bit of background so we can prep the back buffer; do this by 00536 //rendering the card stack (minus the card we are dragging) to the temporary 00537 //background buffer, so it appears if we have lifted the card from the stack 00538 //--SetRect(&rect, 0, 0, nDragCardWidth, nDragCardHeight); 00539 //--PaintRect(hdcBackGnd, &rect, crBackgnd); 00540 00541 int threedadjust = numcards % nThreedCount == 0; 00542 00543 numunder = CalcApparentCards(numcards); 00544 iwhichcard = (numcards+numtodrag) - numunder - 1; 00545 if(nThreedCount == 1) iwhichcard = 0; 00546 00547 int xoff = calc_offset(xoffset, numunder, numtodrag, numunder); 00548 int yoff = calc_offset(yoffset, numunder, numtodrag, numunder); 00549 00550 parentWnd.PaintCardRgn(hdcBackGnd, 0,0, nDragCardWidth,nDragCardHeight, xpos - xoff,ypos - yoff); 00551 00552 // 00553 // Render the cardstack into the back-buffer. The stack 00554 // has already had the dragcards removed, so just draw 00555 // what is left 00556 // 00557 for(icard = 0; icard < numunder; icard++) 00558 { 00559 Card card = cardstack.cardlist[iwhichcard]; 00560 int nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx; 00561 00562 CardBlt(hdcBackGnd, 00563 xoffset * icard - xoffset*(numunder-numtodrag+threedadjust), 00564 yoffset * icard - yoffset*(numunder-numtodrag+threedadjust), 00565 nCardVal); 00566 00567 iwhichcard++; 00568 } 00569 00570 // 00571 // If there are no cards under this one, just draw the place holder 00572 // 00573 if(numcards == 0) 00574 { 00575 switch(uEmptyImage) 00576 { 00577 case CS_EI_NONE: 00578 //no need! we've already cleared the whole 00579 //back-buffer before the main loop! 00580 //SetRect(&rect, 0, 0, __cardwidth, __cardheight); 00581 //PaintRect(hdcBackGnd, &rect, MAKE_PALETTERGB(crBackgnd)); 00582 break; 00583 00584 case CS_EI_SUNK: 00585 DrawCard(hdcBackGnd, 0, 0, __hdcPlaceHolder, __cardwidth, __cardheight); 00586 break; 00587 00588 case CS_EI_CIRC: 00589 case CS_EI_X: 00590 CardBlt(hdc, 0, 0, uEmptyImage); 00591 break; 00592 } 00593 } 00594 00595 // 00596 // now render the drag-cards into the dragcard image 00597 // 00598 PaintRect(hdcDragCard, &rect, crBackgnd); 00599 00600 for(icard = 0; icard < numtodrag; icard++) 00601 { 00602 Card card = dragstack.cardlist[icard]; 00603 int nCardVal = card.FaceUp() ? card.Idx() : nBackCardIdx; 00604 00605 CardBlt(hdcDragCard, xoffset * icard, yoffset * icard, nCardVal); 00606 } 00607 } 00608 00609 void CardRegion::ReleaseDragBitmaps(void) 00610 { 00611 //SelectObject(hdcBackGnd, hOld1); 00612 DeleteObject(hbmBackGnd); 00613 DeleteDC(hdcBackGnd); 00614 00615 //SelectObject(hdcDragCard, hOld2); 00616 DeleteObject(hbmDragCard); 00617 DeleteDC(hdcDragCard); 00618 } 00619 00620 00621 void CardRegion::Redraw() 00622 { 00623 HDC hdc = GetDC((HWND)parentWnd); 00624 00625 Update(); 00626 Render(hdc); 00627 00628 ReleaseDC((HWND)parentWnd, hdc); 00629 } Generated on Thu Feb 9 04:59:25 2012 for ReactOS by
1.6.3
|