// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // Copyright (C) 1999-2003 Forgotten // Copyright (C) 2004 Forgotten and the VBA development team // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or(at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // BitmapControl.cpp : implementation file // #include "stdafx.h" #include "vba.h" #include "BitmapControl.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif bool BitmapControl::isRegistered = false; ///////////////////////////////////////////////////////////////////////////// // BitmapControl IMPLEMENT_DYNCREATE(BitmapControl, CScrollView) BitmapControl::BitmapControl() { w = 0; h = 0; data = NULL; bmpInfo = NULL; stretch = false; registerClass(); CSize sizeTotal; sizeTotal.cx = sizeTotal.cy = 0; SetScrollSizes(MM_TEXT, sizeTotal); } BitmapControl::~BitmapControl() { } BEGIN_MESSAGE_MAP(BitmapControl, CScrollView) //{{AFX_MSG_MAP(BitmapControl) ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_LBUTTONDOWN() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // BitmapControl drawing void BitmapControl::OnInitialUpdate() { CScrollView::OnInitialUpdate(); CSize sizeTotal; // TODO: calculate the total size of this view sizeTotal.cx = sizeTotal.cy = 100; SetScrollSizes(MM_TEXT, sizeTotal); } void BitmapControl::OnDraw(CDC* dc) { RECT r; GetClientRect(&r); int w1 = r.right - r.left; int h1 = r.bottom - r.top; CDC memDC; memDC.CreateCompatibleDC(dc); if(!stretch) { if(w > w1) w1 = w; if(h > h1) h1 = h; } CBitmap bitmap, *pOldBitmap; bitmap.CreateCompatibleBitmap(dc, w1, h1); pOldBitmap = memDC.SelectObject(&bitmap); if(stretch) { bmpInfo->bmiHeader.biWidth = w; bmpInfo->bmiHeader.biHeight = -h; StretchDIBits(memDC.GetSafeHdc(), 0, 0, w1, h1, 0, 0, w, h, data, bmpInfo, DIB_RGB_COLORS, SRCCOPY); } else { FillOutsideRect(&memDC, CBrush::FromHandle(GetSysColorBrush(COLOR_BTNFACE))); bmpInfo->bmiHeader.biWidth = w; bmpInfo->bmiHeader.biHeight = -h; SetDIBitsToDevice(memDC.GetSafeHdc(), 0, 0, w, h, 0, 0, 0, h, data, bmpInfo, DIB_RGB_COLORS); } dc->BitBlt(0,0,w1,h1, &memDC,0,0,SRCCOPY); memDC.SelectObject(pOldBitmap); bitmap.DeleteObject(); memDC.DeleteDC(); } ///////////////////////////////////////////////////////////////////////////// // BitmapControl diagnostics #ifdef _DEBUG void BitmapControl::AssertValid() const { CScrollView::AssertValid(); } void BitmapControl::Dump(CDumpContext& dc) const { CScrollView::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // BitmapControl message handlers BOOL BitmapControl::OnEraseBkgnd(CDC* pDC) { return TRUE; } void BitmapControl::OnSize(UINT nType, int cx, int cy) { if(!stretch) CScrollView::OnSize(nType, cx, cy); } void BitmapControl::OnLButtonDown(UINT nFlags, CPoint pt) { if(!data) return; int x = pt.x; int y = pt.y; WPARAM point; if(stretch) { RECT rect; GetClientRect(&rect); int height = rect.bottom - rect.top; int width = rect.right - rect.left; int xx = (x * w) / width; int yy = (y * h) / height; point = xx | (yy<<16); int xxx = xx / 8; int yyy = yy / 8; for(int i = 0; i < 8; i++) { memcpy(&colors[i*3*8], &data[xxx * 8 * 3 + w * yyy * 8 * 3 + i * w * 3], 8 * 3); } } else { POINT p; p.x = GetScrollPos(SB_HORZ); p.y = GetScrollPos(SB_VERT); p.x += x; p.y += y; if(p.x >= w || p.y >= h) return; point = p.x | (p.y<<16); int xxx = p.x / 8; int yyy = p.y / 8; for(int i = 0; i < 8; i++) { memcpy(&colors[i*3*8], &data[xxx * 8 * 3 + w * yyy * 8 * 3 + i * w * 3], 8 * 3); } } GetParent()->SendMessage(WM_MAPINFO, point, (LPARAM)colors); } void BitmapControl::setBmpInfo(BITMAPINFO *info) { bmpInfo = info; } void BitmapControl::setData(u8 *d) { data = d; } void BitmapControl::setSize(int w1, int h1) { if(w != w1 || h != h1) { w = w1; h = h1; SIZE s; s.cx = w; s.cy = h; SetScrollSizes(MM_TEXT, s); } } void BitmapControl::refresh() { Invalidate(); } void BitmapControl::registerClass() { if(!isRegistered) { WNDCLASS wc; ZeroMemory(&wc, sizeof(wc)); wc.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; wc.lpfnWndProc = (WNDPROC)::DefWindowProc; wc.hInstance = AfxGetInstanceHandle(); wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "VbaBitmapControl"; AfxRegisterClass(&wc); isRegistered = true; } } void BitmapControl::setStretch(bool b) { if(b != stretch) { stretch = b; Invalidate(); } } bool BitmapControl::getStretch() { return stretch; } void BitmapControl::PostNcDestroy() { }