diff src/gtk/screenarea.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/gtk/screenarea.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,293 @@
     1.4 +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
     1.5 +// Copyright (C) 1999-2003 Forgotten
     1.6 +// Copyright (C) 2004 Forgotten and the VBA development team
     1.7 +
     1.8 +// This program is free software; you can redistribute it and/or modify
     1.9 +// it under the terms of the GNU General Public License as published by
    1.10 +// the Free Software Foundation; either version 2, or(at your option)
    1.11 +// any later version.
    1.12 +//
    1.13 +// This program is distributed in the hope that it will be useful,
    1.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.16 +// GNU General Public License for more details.
    1.17 +//
    1.18 +// You should have received a copy of the GNU General Public License
    1.19 +// along with this program; if not, write to the Free Software Foundation,
    1.20 +// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    1.21 +
    1.22 +#include "screenarea.h"
    1.23 +
    1.24 +#include <string.h>
    1.25 +
    1.26 +namespace VBA
    1.27 +{
    1.28 +
    1.29 +ScreenArea::ScreenArea(int _iWidth, int _iHeight, int _iScale) :
    1.30 +  m_puiPixels(NULL),
    1.31 +  m_puiDelta(NULL),
    1.32 +  m_vFilter2x(NULL),
    1.33 +  m_vFilterIB(NULL),
    1.34 +  m_bShowCursor(true)
    1.35 +{
    1.36 +  g_assert(_iWidth >= 1 && _iHeight >= 1 && _iScale >= 1);
    1.37 +
    1.38 +  m_iWidth  = _iWidth;
    1.39 +  m_iHeight = _iHeight;
    1.40 +  m_iScale  = _iScale;
    1.41 +  vUpdateSize();
    1.42 +
    1.43 +  set_events(Gdk::EXPOSURE_MASK
    1.44 +             | Gdk::POINTER_MOTION_MASK
    1.45 +             | Gdk::ENTER_NOTIFY_MASK
    1.46 +             | Gdk::LEAVE_NOTIFY_MASK);
    1.47 +
    1.48 +  char aiEmptyData[8];
    1.49 +  memset(aiEmptyData, 0, sizeof(aiEmptyData));
    1.50 +  Glib::RefPtr<Gdk::Bitmap> poSource = Gdk::Bitmap::create(aiEmptyData, 8, 8);
    1.51 +  Glib::RefPtr<Gdk::Bitmap> poMask = Gdk::Bitmap::create(aiEmptyData, 8, 8);
    1.52 +  Gdk::Color oFg;
    1.53 +  Gdk::Color oBg;
    1.54 +  oFg.set_rgb(0, 0, 0);
    1.55 +  oBg.set_rgb(0, 0, 0);
    1.56 +
    1.57 +  m_poEmptyCursor = new Gdk::Cursor(poSource, poMask, oFg, oBg, 0, 0);
    1.58 +}
    1.59 +
    1.60 +ScreenArea::~ScreenArea()
    1.61 +{
    1.62 +  if (m_puiPixels != NULL)
    1.63 +  {
    1.64 +    delete[] m_puiPixels;
    1.65 +  }
    1.66 +
    1.67 +  if (m_puiDelta != NULL)
    1.68 +  {
    1.69 +    delete[] m_puiDelta;
    1.70 +  }
    1.71 +
    1.72 +  if (m_poEmptyCursor != NULL)
    1.73 +  {
    1.74 +    delete m_poEmptyCursor;
    1.75 +  }
    1.76 +}
    1.77 +
    1.78 +void ScreenArea::vSetSize(int _iWidth, int _iHeight)
    1.79 +{
    1.80 +  g_return_if_fail(_iWidth >= 1 && _iHeight >= 1);
    1.81 +
    1.82 +  if (_iWidth != m_iWidth || _iHeight != m_iHeight)
    1.83 +  {
    1.84 +    m_iWidth  = _iWidth;
    1.85 +    m_iHeight = _iHeight;
    1.86 +    vUpdateSize();
    1.87 +  }
    1.88 +}
    1.89 +
    1.90 +void ScreenArea::vSetScale(int _iScale)
    1.91 +{
    1.92 +  g_return_if_fail(_iScale >= 1);
    1.93 +
    1.94 +  if (_iScale != m_iScale)
    1.95 +  {
    1.96 +    m_iScale = _iScale;
    1.97 +    vUpdateSize();
    1.98 +  }
    1.99 +}
   1.100 +
   1.101 +void ScreenArea::vSetFilter2x(EFilter2x _eFilter2x)
   1.102 +{
   1.103 +  m_vFilter2x = pvGetFilter2x(_eFilter2x, FilterDepth32);
   1.104 +}
   1.105 +
   1.106 +void ScreenArea::vSetFilterIB(EFilterIB _eFilterIB)
   1.107 +{
   1.108 +  m_vFilterIB = pvGetFilterIB(_eFilterIB, FilterDepth32);
   1.109 +}
   1.110 +
   1.111 +void ScreenArea::vDrawPixels(u8 * _puiData)
   1.112 +{
   1.113 +  if (m_vFilterIB != NULL)
   1.114 +  {
   1.115 +    m_vFilterIB(_puiData + m_iAreaWidth * 2 + 4,
   1.116 +                m_iAreaWidth * 2 + 4,
   1.117 +                m_iWidth,
   1.118 +                m_iHeight);
   1.119 +  }
   1.120 +
   1.121 +  if (m_iScale == 1)
   1.122 +  {
   1.123 +    u32 * puiSrc = (u32 *)_puiData + m_iWidth + 1;
   1.124 +    u32 * puiPixel = m_puiPixels;
   1.125 +    for (int y = 0; y < m_iHeight; y++)
   1.126 +    {
   1.127 +      for (int x = 0; x < m_iWidth; x++)
   1.128 +      {
   1.129 +        *puiPixel++ = *puiSrc++;
   1.130 +      }
   1.131 +      puiSrc++;
   1.132 +    }
   1.133 +  }
   1.134 +  else if (m_iScale == 2 && m_vFilter2x != NULL)
   1.135 +  {
   1.136 +    m_vFilter2x(_puiData + m_iAreaWidth * 2 + 4,
   1.137 +                m_iAreaWidth * 2 + 4,
   1.138 +                m_puiDelta,
   1.139 +                (u8 *)m_puiPixels,
   1.140 +                m_iRowStride,
   1.141 +                m_iWidth,
   1.142 +                m_iHeight);
   1.143 +  }
   1.144 +  else
   1.145 +  {
   1.146 +    u32 * puiSrc = (u32 *)_puiData + m_iWidth + 1;
   1.147 +    u32 * puiSrc2;
   1.148 +    u32 * puiPixel = m_puiPixels;
   1.149 +    for (int y = 0; y < m_iHeight; y++)
   1.150 +    {
   1.151 +      for (int j = 0; j < m_iScale; j++)
   1.152 +      {
   1.153 +        puiSrc2 = puiSrc;
   1.154 +        for (int x = 0; x < m_iWidth; x++)
   1.155 +        {
   1.156 +          for (int i = 0; i < m_iScale; i++)
   1.157 +          {
   1.158 +            *puiPixel++ = *puiSrc2;
   1.159 +          }
   1.160 +          puiSrc2++;
   1.161 +        }
   1.162 +      }
   1.163 +      puiSrc = puiSrc2 + 1;
   1.164 +    }
   1.165 +  }
   1.166 +
   1.167 +  queue_draw_area(0, 0, m_iAreaWidth, m_iAreaHeight);
   1.168 +}
   1.169 +
   1.170 +void ScreenArea::vDrawColor(u32 _uiColor)
   1.171 +{
   1.172 +  _uiColor = GUINT32_TO_BE(_uiColor) << 8;
   1.173 +
   1.174 +  u32 * puiPixel = m_puiPixels;
   1.175 +  u32 * puiEnd   = m_puiPixels + m_iAreaWidth * m_iAreaHeight;
   1.176 +  while (puiPixel != puiEnd)
   1.177 +  {
   1.178 +    *puiPixel++ = _uiColor;
   1.179 +  }
   1.180 +
   1.181 +  queue_draw_area(0, 0, m_iAreaWidth, m_iAreaHeight);
   1.182 +}
   1.183 +
   1.184 +void ScreenArea::vUpdateSize()
   1.185 +{
   1.186 +  if (m_puiPixels != NULL)
   1.187 +  {
   1.188 +    delete[] m_puiPixels;
   1.189 +  }
   1.190 +
   1.191 +  if (m_puiDelta != NULL)
   1.192 +  {
   1.193 +    delete[] m_puiDelta;
   1.194 +  }
   1.195 +
   1.196 +  m_iAreaWidth  = m_iScale * m_iWidth;
   1.197 +  m_iAreaHeight = m_iScale * m_iHeight;
   1.198 +  m_iRowStride  = m_iAreaWidth * 4;
   1.199 +
   1.200 +  m_puiPixels = new u32[m_iAreaWidth * m_iAreaHeight];
   1.201 +
   1.202 +  m_puiDelta = new u8[(m_iWidth + 2) * (m_iHeight + 2) * 4];
   1.203 +  memset(m_puiDelta, 255, (m_iWidth + 2) * (m_iHeight + 2) * 4);
   1.204 +
   1.205 +  set_size_request(m_iAreaWidth, m_iAreaHeight);
   1.206 +}
   1.207 +
   1.208 +void ScreenArea::vStartCursorTimeout()
   1.209 +{
   1.210 +  m_oCursorSig.disconnect();
   1.211 +  m_oCursorSig = Glib::signal_timeout().connect(
   1.212 +    SigC::slot(*this, &ScreenArea::bOnCursorTimeout),
   1.213 +    2000);
   1.214 +}
   1.215 +
   1.216 +void ScreenArea::vStopCursorTimeout()
   1.217 +{
   1.218 +  m_oCursorSig.disconnect();
   1.219 +}
   1.220 +
   1.221 +void ScreenArea::vHideCursor()
   1.222 +{
   1.223 +  get_window()->set_cursor(*m_poEmptyCursor);
   1.224 +  m_bShowCursor = false;
   1.225 +}
   1.226 +
   1.227 +void ScreenArea::vShowCursor()
   1.228 +{
   1.229 +  get_window()->set_cursor();
   1.230 +  m_bShowCursor = true;
   1.231 +}
   1.232 +
   1.233 +bool ScreenArea::on_expose_event(GdkEventExpose * _pstEvent)
   1.234 +{
   1.235 +  if (_pstEvent->area.x + _pstEvent->area.width > m_iAreaWidth
   1.236 +      || _pstEvent->area.y + _pstEvent->area.height > m_iAreaHeight)
   1.237 +  {
   1.238 +    return false;
   1.239 +  }
   1.240 +
   1.241 +  guchar * puiAreaPixels = (guchar *)m_puiPixels;
   1.242 +
   1.243 +  if (_pstEvent->area.x != 0)
   1.244 +  {
   1.245 +    puiAreaPixels += _pstEvent->area.x << 2;
   1.246 +  }
   1.247 +
   1.248 +  if (_pstEvent->area.y != 0)
   1.249 +  {
   1.250 +    puiAreaPixels += _pstEvent->area.y * m_iRowStride;
   1.251 +  }
   1.252 +
   1.253 +  get_window()->draw_rgb_32_image(get_style()->get_fg_gc(get_state()),
   1.254 +                                  _pstEvent->area.x,
   1.255 +                                  _pstEvent->area.y,
   1.256 +                                  _pstEvent->area.width,
   1.257 +                                  _pstEvent->area.height,
   1.258 +                                  Gdk::RGB_DITHER_MAX,
   1.259 +                                  puiAreaPixels,
   1.260 +                                  m_iRowStride);
   1.261 +  return true;
   1.262 +}
   1.263 +
   1.264 +bool ScreenArea::on_motion_notify_event(GdkEventMotion * _pstEvent)
   1.265 +{
   1.266 +  if (! m_bShowCursor)
   1.267 +  {
   1.268 +    vShowCursor();
   1.269 +  }
   1.270 +  vStartCursorTimeout();
   1.271 +  return false;
   1.272 +}
   1.273 +
   1.274 +bool ScreenArea::on_enter_notify_event(GdkEventCrossing * _pstEvent)
   1.275 +{
   1.276 +  vStartCursorTimeout();
   1.277 +  return false;
   1.278 +}
   1.279 +
   1.280 +bool ScreenArea::on_leave_notify_event(GdkEventCrossing * _pstEvent)
   1.281 +{
   1.282 +  vStopCursorTimeout();
   1.283 +  if (! m_bShowCursor)
   1.284 +  {
   1.285 +    vShowCursor();
   1.286 +  }
   1.287 +  return false;
   1.288 +}
   1.289 +
   1.290 +bool ScreenArea::bOnCursorTimeout()
   1.291 +{
   1.292 +  vHideCursor();
   1.293 +  return false;
   1.294 +}
   1.295 +
   1.296 +} // namespace VBA