#define STRICT
#define ORBITER_MODULE
#include <orbitersdk.h>
#include <iostream>
HDC hOrbWindow=0;
DWORD width=0, height=0;
DLLCLBK void opcOpenRenderViewport(HWND hWnd, DWORD w, DWORD h, BOOL fc)
{
hOrbWindow=GetDC(hWnd);
width=w;height=h;
}
// below two functions copied from MSDN
PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp)
{
BITMAP bmp;
PBITMAPINFO pbmi;
WORD cClrBits;
// Retrieve the bitmap color format, width, and height.
if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) {
return NULL;
}
cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
if (cClrBits == 1)
cClrBits = 1;
else if (cClrBits <= 4)
cClrBits = 4;
else if (cClrBits <= 8)
cClrBits = 8;
else if (cClrBits <= 16)
cClrBits = 16;
else if (cClrBits <= 24)
cClrBits = 24;
else cClrBits = 32;
if (cClrBits != 24)
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * (1<< cClrBits));
else
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER));
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bmp.bmWidth;
pbmi->bmiHeader.biHeight = bmp.bmHeight;
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
if (cClrBits < 24)
pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
* pbmi->bmiHeader.biHeight;
pbmi->bmiHeader.biClrImportant = 0;
return pbmi;
}
bool CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi,
HBITMAP hBMP, HDC hDC) {
HANDLE hf; // file handle
BITMAPFILEHEADER hdr; // bitmap file-header
PBITMAPINFOHEADER pbih; // bitmap info-header
LPBYTE lpBits; // memory pointer
DWORD dwTotal; // total count of bytes
DWORD cb; // incremental count of bytes
BYTE *hp; // byte pointer
DWORD dwTmp;
pbih = (PBITMAPINFOHEADER) pbi;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
if (!lpBits) {
return false;
}
// Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS)) {
return false;
}
// Create the .BMP file.
hf = CreateFile(pszFile,
GENERIC_READ | GENERIC_WRITE,
(DWORD) 0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hf == INVALID_HANDLE_VALUE) {
return false;
}
hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"
// Compute the size of the entire file.
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof(RGBQUAD) + pbih->biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
// Compute the offset to the array of color indices.
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof (RGBQUAD);
// Copy the BITMAPFILEHEADER into the .BMP file.
if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
(LPDWORD) &dwTmp, NULL))
{
return false;
}
// Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof (RGBQUAD),
(LPDWORD) &dwTmp, NULL)) {
return false;
}
// Copy the array of color indices into the .BMP file.
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) {
return false;
}
// Close the .BMP file.
if (!CloseHandle(hf)) {
return false;
}
// Free memory.
GlobalFree((HGLOBAL)lpBits);
return true;
}
DLLCLBK void opcPreStep(double simt, double simdt, double mjd)
{
static double ltime = simt;
if ( GetAsyncKeyState(VK_F10) && simt-ltime > 0.4)
{
HDC hMemDC = CreateCompatibleDC(hOrbWindow);
HBITMAP hBitmap = CreateCompatibleBitmap(hOrbWindow, width, height);
HBITMAP hOld = (HBITMAP) SelectObject(hMemDC, hBitmap);
BitBlt(hMemDC, 0, 0, width, height, hOrbWindow,
0, 0, SRCCOPY);
// drawing stuff
for ( int i = 0; i < 100; i++ ){
MoveToEx(hMemDC, rand()%width, rand()%height, NULL);
LineTo(hMemDC, rand()%width, rand()%height);
}
SelectObject(hMemDC, hOld);
DeleteDC(hMemDC);
PBITMAPINFO bitmapInfo = CreateBitmapInfoStruct(hBitmap);
CreateBMPFile("screenie.bmp", bitmapInfo, hBitmap, hOrbWindow);
DeleteObject(hBitmap);
ltime=simt;
}
}