Shadowrun: Awakened 29 September 2011 - Build 871
gdivideo.cpp
Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2010 Intel Corporation.  All Rights Reserved.
00003 
00004     This file is part of Threading Building Blocks.
00005 
00006     Threading Building Blocks is free software; you can redistribute it
00007     and/or modify it under the terms of the GNU General Public License
00008     version 2 as published by the Free Software Foundation.
00009 
00010     Threading Building Blocks is distributed in the hope that it will be
00011     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00012     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with Threading Building Blocks; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019     As a special exception, you may use this file as part of a free software
00020     library without restriction.  Specifically, if other files instantiate
00021     templates or use macros or inline functions from this file, or you compile
00022     this file and link it with other files to produce an executable, this
00023     file does not by itself cause the resulting executable to be covered by
00024     the GNU General Public License.  This exception does not however
00025     invalidate any other reasons why the executable file might be covered by
00026     the GNU General Public License.
00027 */
00028 
00029 // common Windows parts
00030 #include "winvideo.h"
00031 // include GDI+ headers
00032 #include <gdiplus.h>
00033 // and another headers
00034 #include <stdio.h>
00035 
00036 // tag linking library
00037 #pragma comment(lib, "gdiplus.lib")
00038 
00039 // global specific variables
00040 Gdiplus::Bitmap *           g_pBitmap;           // main drawing bitmap
00041 ULONG_PTR                   gdiplusToken;
00042 Gdiplus::GdiplusStartupInput gdiplusStartupInput;// GDI+
00043 
00045 bool DisplayError(LPSTR lpstrErr, HRESULT hres)
00046 {
00047     static bool InError = false;
00048     int retval = 0;
00049     if (!InError)
00050     {
00051         InError = true;
00052         LPCSTR lpMsgBuf;
00053         if(!hres) hres = GetLastError();
00054         FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
00055                                NULL, hres, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL );
00056         retval = MessageBox(g_hAppWnd, lpstrErr, lpMsgBuf, MB_OK|MB_ICONERROR);
00057         LocalFree( (HLOCAL)lpMsgBuf );
00058         InError = false;
00059     }
00060     return false;
00061 }
00062 
00064 LRESULT CALLBACK InternalWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
00065 {
00066     switch (iMsg)
00067     {
00068         case WM_MOVE:
00069             // Check to make sure our window exists before we tell it to repaint.
00070             // This will fail the first time (while the window is being created).
00071             if (hwnd) {
00072                 InvalidateRect(hwnd, NULL, FALSE);
00073                 UpdateWindow(hwnd);
00074             }
00075             return 0L;
00076 
00077         case WM_PAINT:
00078             {
00079                 PAINTSTRUCT ps;
00080                 Gdiplus::Graphics graphics( BeginPaint(hwnd, &ps) );
00081                 // redraw just requested area. This call is as fast as simple DrawImage() call.
00082                 if(g_video->updating) graphics.DrawImage(g_pBitmap, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.left, ps.rcPaint.top,
00083                                     ps.rcPaint.right, ps.rcPaint.bottom, Gdiplus::UnitPixel);
00084                 EndPaint(hwnd, &ps);
00085             }
00086             return 0L;
00087 
00088         // Proccess all mouse and keyboard events
00089         case WM_LBUTTONDOWN:    g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), 1); break;
00090         case WM_LBUTTONUP:      g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), -1); break;
00091         case WM_RBUTTONDOWN:    g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), 2); break;
00092         case WM_RBUTTONUP:      g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), -2); break;
00093         case WM_MBUTTONDOWN:    g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), 3); break;
00094         case WM_MBUTTONUP:      g_video->on_mouse( (int)LOWORD(lParam), (int)HIWORD(lParam), -3); break;
00095         case WM_CHAR:           g_video->on_key( (int)wParam); break;
00096 
00097         // some useless stuff
00098         case WM_ERASEBKGND:     return 1;  // keeps erase-background events from happening, reduces chop
00099         case WM_DISPLAYCHANGE:  return 0;
00100 
00101         // Now, shut down the window...
00102         case WM_DESTROY:        PostQuitMessage(0); return 0;
00103     }
00104     // call user defined proc, if exists
00105     return g_pUserProc? g_pUserProc(hwnd, iMsg, wParam, lParam) : DefWindowProc(hwnd, iMsg, wParam, lParam);
00106 }
00107 
00109 
00110 bool video::init_window(int sizex, int sizey)
00111 {
00112     assert(win_hInstance != 0);
00113     g_sizex = sizex; g_sizey = sizey;
00114     if (!WinInit(win_hInstance, win_iCmdShow, gWndClass, title, true)) {
00115         DisplayError("Unable to initialize the program's window.");
00116         return false;
00117     }
00118     ShowWindow(g_hAppWnd, SW_SHOW);
00119     Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
00120     g_pImg = new unsigned int[sizex*sizey];
00121     g_pBitmap = new Gdiplus::Bitmap(g_sizex, g_sizey, 4*g_sizex, PixelFormat32bppRGB, (BYTE*)g_pImg );
00122     running = true;
00123     return true;
00124 }
00125 
00126 void video::terminate()
00127 {
00128     if(g_pBitmap) { delete g_pBitmap; g_pBitmap = 0; }
00129     Gdiplus::GdiplusShutdown(gdiplusToken);
00130     g_video = 0; running = false;
00131     if(g_pImg) { delete[] g_pImg; g_pImg = 0; }
00132 }
00133 
00135 
00136 drawing_area::drawing_area(int x, int y, int sizex, int sizey)
00137 : start_x(x), start_y(y), size_x(sizex), size_y(sizey), pixel_depth(24),
00138     base_index(y*g_sizex + x), max_index(g_sizex*g_sizey), index_stride(g_sizex), ptr32(g_pImg)
00139 {
00140     assert(x < g_sizex); assert(y < g_sizey);
00141     assert(x+sizex <= g_sizex); assert(y+sizey <= g_sizey);
00142 
00143     index = base_index; // current index
00144 }
00145 
00146 drawing_area::~drawing_area()
00147 {
00148     if(g_video->updating) {
00149         RECT r;
00150         r.left = start_x; r.right  = start_x + size_x;
00151         r.top  = start_y; r.bottom = start_y + size_y;
00152         InvalidateRect(g_hAppWnd, &r, false);
00153     }
00154 }

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net