annotate 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
rev   line source
rlm@1 1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
rlm@1 2 // Copyright (C) 1999-2003 Forgotten
rlm@1 3 // Copyright (C) 2004 Forgotten and the VBA development team
rlm@1 4
rlm@1 5 // This program is free software; you can redistribute it and/or modify
rlm@1 6 // it under the terms of the GNU General Public License as published by
rlm@1 7 // the Free Software Foundation; either version 2, or(at your option)
rlm@1 8 // any later version.
rlm@1 9 //
rlm@1 10 // This program is distributed in the hope that it will be useful,
rlm@1 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
rlm@1 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
rlm@1 13 // GNU General Public License for more details.
rlm@1 14 //
rlm@1 15 // You should have received a copy of the GNU General Public License
rlm@1 16 // along with this program; if not, write to the Free Software Foundation,
rlm@1 17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
rlm@1 18
rlm@1 19 #include "screenarea.h"
rlm@1 20
rlm@1 21 #include <string.h>
rlm@1 22
rlm@1 23 namespace VBA
rlm@1 24 {
rlm@1 25
rlm@1 26 ScreenArea::ScreenArea(int _iWidth, int _iHeight, int _iScale) :
rlm@1 27 m_puiPixels(NULL),
rlm@1 28 m_puiDelta(NULL),
rlm@1 29 m_vFilter2x(NULL),
rlm@1 30 m_vFilterIB(NULL),
rlm@1 31 m_bShowCursor(true)
rlm@1 32 {
rlm@1 33 g_assert(_iWidth >= 1 && _iHeight >= 1 && _iScale >= 1);
rlm@1 34
rlm@1 35 m_iWidth = _iWidth;
rlm@1 36 m_iHeight = _iHeight;
rlm@1 37 m_iScale = _iScale;
rlm@1 38 vUpdateSize();
rlm@1 39
rlm@1 40 set_events(Gdk::EXPOSURE_MASK
rlm@1 41 | Gdk::POINTER_MOTION_MASK
rlm@1 42 | Gdk::ENTER_NOTIFY_MASK
rlm@1 43 | Gdk::LEAVE_NOTIFY_MASK);
rlm@1 44
rlm@1 45 char aiEmptyData[8];
rlm@1 46 memset(aiEmptyData, 0, sizeof(aiEmptyData));
rlm@1 47 Glib::RefPtr<Gdk::Bitmap> poSource = Gdk::Bitmap::create(aiEmptyData, 8, 8);
rlm@1 48 Glib::RefPtr<Gdk::Bitmap> poMask = Gdk::Bitmap::create(aiEmptyData, 8, 8);
rlm@1 49 Gdk::Color oFg;
rlm@1 50 Gdk::Color oBg;
rlm@1 51 oFg.set_rgb(0, 0, 0);
rlm@1 52 oBg.set_rgb(0, 0, 0);
rlm@1 53
rlm@1 54 m_poEmptyCursor = new Gdk::Cursor(poSource, poMask, oFg, oBg, 0, 0);
rlm@1 55 }
rlm@1 56
rlm@1 57 ScreenArea::~ScreenArea()
rlm@1 58 {
rlm@1 59 if (m_puiPixels != NULL)
rlm@1 60 {
rlm@1 61 delete[] m_puiPixels;
rlm@1 62 }
rlm@1 63
rlm@1 64 if (m_puiDelta != NULL)
rlm@1 65 {
rlm@1 66 delete[] m_puiDelta;
rlm@1 67 }
rlm@1 68
rlm@1 69 if (m_poEmptyCursor != NULL)
rlm@1 70 {
rlm@1 71 delete m_poEmptyCursor;
rlm@1 72 }
rlm@1 73 }
rlm@1 74
rlm@1 75 void ScreenArea::vSetSize(int _iWidth, int _iHeight)
rlm@1 76 {
rlm@1 77 g_return_if_fail(_iWidth >= 1 && _iHeight >= 1);
rlm@1 78
rlm@1 79 if (_iWidth != m_iWidth || _iHeight != m_iHeight)
rlm@1 80 {
rlm@1 81 m_iWidth = _iWidth;
rlm@1 82 m_iHeight = _iHeight;
rlm@1 83 vUpdateSize();
rlm@1 84 }
rlm@1 85 }
rlm@1 86
rlm@1 87 void ScreenArea::vSetScale(int _iScale)
rlm@1 88 {
rlm@1 89 g_return_if_fail(_iScale >= 1);
rlm@1 90
rlm@1 91 if (_iScale != m_iScale)
rlm@1 92 {
rlm@1 93 m_iScale = _iScale;
rlm@1 94 vUpdateSize();
rlm@1 95 }
rlm@1 96 }
rlm@1 97
rlm@1 98 void ScreenArea::vSetFilter2x(EFilter2x _eFilter2x)
rlm@1 99 {
rlm@1 100 m_vFilter2x = pvGetFilter2x(_eFilter2x, FilterDepth32);
rlm@1 101 }
rlm@1 102
rlm@1 103 void ScreenArea::vSetFilterIB(EFilterIB _eFilterIB)
rlm@1 104 {
rlm@1 105 m_vFilterIB = pvGetFilterIB(_eFilterIB, FilterDepth32);
rlm@1 106 }
rlm@1 107
rlm@1 108 void ScreenArea::vDrawPixels(u8 * _puiData)
rlm@1 109 {
rlm@1 110 if (m_vFilterIB != NULL)
rlm@1 111 {
rlm@1 112 m_vFilterIB(_puiData + m_iAreaWidth * 2 + 4,
rlm@1 113 m_iAreaWidth * 2 + 4,
rlm@1 114 m_iWidth,
rlm@1 115 m_iHeight);
rlm@1 116 }
rlm@1 117
rlm@1 118 if (m_iScale == 1)
rlm@1 119 {
rlm@1 120 u32 * puiSrc = (u32 *)_puiData + m_iWidth + 1;
rlm@1 121 u32 * puiPixel = m_puiPixels;
rlm@1 122 for (int y = 0; y < m_iHeight; y++)
rlm@1 123 {
rlm@1 124 for (int x = 0; x < m_iWidth; x++)
rlm@1 125 {
rlm@1 126 *puiPixel++ = *puiSrc++;
rlm@1 127 }
rlm@1 128 puiSrc++;
rlm@1 129 }
rlm@1 130 }
rlm@1 131 else if (m_iScale == 2 && m_vFilter2x != NULL)
rlm@1 132 {
rlm@1 133 m_vFilter2x(_puiData + m_iAreaWidth * 2 + 4,
rlm@1 134 m_iAreaWidth * 2 + 4,
rlm@1 135 m_puiDelta,
rlm@1 136 (u8 *)m_puiPixels,
rlm@1 137 m_iRowStride,
rlm@1 138 m_iWidth,
rlm@1 139 m_iHeight);
rlm@1 140 }
rlm@1 141 else
rlm@1 142 {
rlm@1 143 u32 * puiSrc = (u32 *)_puiData + m_iWidth + 1;
rlm@1 144 u32 * puiSrc2;
rlm@1 145 u32 * puiPixel = m_puiPixels;
rlm@1 146 for (int y = 0; y < m_iHeight; y++)
rlm@1 147 {
rlm@1 148 for (int j = 0; j < m_iScale; j++)
rlm@1 149 {
rlm@1 150 puiSrc2 = puiSrc;
rlm@1 151 for (int x = 0; x < m_iWidth; x++)
rlm@1 152 {
rlm@1 153 for (int i = 0; i < m_iScale; i++)
rlm@1 154 {
rlm@1 155 *puiPixel++ = *puiSrc2;
rlm@1 156 }
rlm@1 157 puiSrc2++;
rlm@1 158 }
rlm@1 159 }
rlm@1 160 puiSrc = puiSrc2 + 1;
rlm@1 161 }
rlm@1 162 }
rlm@1 163
rlm@1 164 queue_draw_area(0, 0, m_iAreaWidth, m_iAreaHeight);
rlm@1 165 }
rlm@1 166
rlm@1 167 void ScreenArea::vDrawColor(u32 _uiColor)
rlm@1 168 {
rlm@1 169 _uiColor = GUINT32_TO_BE(_uiColor) << 8;
rlm@1 170
rlm@1 171 u32 * puiPixel = m_puiPixels;
rlm@1 172 u32 * puiEnd = m_puiPixels + m_iAreaWidth * m_iAreaHeight;
rlm@1 173 while (puiPixel != puiEnd)
rlm@1 174 {
rlm@1 175 *puiPixel++ = _uiColor;
rlm@1 176 }
rlm@1 177
rlm@1 178 queue_draw_area(0, 0, m_iAreaWidth, m_iAreaHeight);
rlm@1 179 }
rlm@1 180
rlm@1 181 void ScreenArea::vUpdateSize()
rlm@1 182 {
rlm@1 183 if (m_puiPixels != NULL)
rlm@1 184 {
rlm@1 185 delete[] m_puiPixels;
rlm@1 186 }
rlm@1 187
rlm@1 188 if (m_puiDelta != NULL)
rlm@1 189 {
rlm@1 190 delete[] m_puiDelta;
rlm@1 191 }
rlm@1 192
rlm@1 193 m_iAreaWidth = m_iScale * m_iWidth;
rlm@1 194 m_iAreaHeight = m_iScale * m_iHeight;
rlm@1 195 m_iRowStride = m_iAreaWidth * 4;
rlm@1 196
rlm@1 197 m_puiPixels = new u32[m_iAreaWidth * m_iAreaHeight];
rlm@1 198
rlm@1 199 m_puiDelta = new u8[(m_iWidth + 2) * (m_iHeight + 2) * 4];
rlm@1 200 memset(m_puiDelta, 255, (m_iWidth + 2) * (m_iHeight + 2) * 4);
rlm@1 201
rlm@1 202 set_size_request(m_iAreaWidth, m_iAreaHeight);
rlm@1 203 }
rlm@1 204
rlm@1 205 void ScreenArea::vStartCursorTimeout()
rlm@1 206 {
rlm@1 207 m_oCursorSig.disconnect();
rlm@1 208 m_oCursorSig = Glib::signal_timeout().connect(
rlm@1 209 SigC::slot(*this, &ScreenArea::bOnCursorTimeout),
rlm@1 210 2000);
rlm@1 211 }
rlm@1 212
rlm@1 213 void ScreenArea::vStopCursorTimeout()
rlm@1 214 {
rlm@1 215 m_oCursorSig.disconnect();
rlm@1 216 }
rlm@1 217
rlm@1 218 void ScreenArea::vHideCursor()
rlm@1 219 {
rlm@1 220 get_window()->set_cursor(*m_poEmptyCursor);
rlm@1 221 m_bShowCursor = false;
rlm@1 222 }
rlm@1 223
rlm@1 224 void ScreenArea::vShowCursor()
rlm@1 225 {
rlm@1 226 get_window()->set_cursor();
rlm@1 227 m_bShowCursor = true;
rlm@1 228 }
rlm@1 229
rlm@1 230 bool ScreenArea::on_expose_event(GdkEventExpose * _pstEvent)
rlm@1 231 {
rlm@1 232 if (_pstEvent->area.x + _pstEvent->area.width > m_iAreaWidth
rlm@1 233 || _pstEvent->area.y + _pstEvent->area.height > m_iAreaHeight)
rlm@1 234 {
rlm@1 235 return false;
rlm@1 236 }
rlm@1 237
rlm@1 238 guchar * puiAreaPixels = (guchar *)m_puiPixels;
rlm@1 239
rlm@1 240 if (_pstEvent->area.x != 0)
rlm@1 241 {
rlm@1 242 puiAreaPixels += _pstEvent->area.x << 2;
rlm@1 243 }
rlm@1 244
rlm@1 245 if (_pstEvent->area.y != 0)
rlm@1 246 {
rlm@1 247 puiAreaPixels += _pstEvent->area.y * m_iRowStride;
rlm@1 248 }
rlm@1 249
rlm@1 250 get_window()->draw_rgb_32_image(get_style()->get_fg_gc(get_state()),
rlm@1 251 _pstEvent->area.x,
rlm@1 252 _pstEvent->area.y,
rlm@1 253 _pstEvent->area.width,
rlm@1 254 _pstEvent->area.height,
rlm@1 255 Gdk::RGB_DITHER_MAX,
rlm@1 256 puiAreaPixels,
rlm@1 257 m_iRowStride);
rlm@1 258 return true;
rlm@1 259 }
rlm@1 260
rlm@1 261 bool ScreenArea::on_motion_notify_event(GdkEventMotion * _pstEvent)
rlm@1 262 {
rlm@1 263 if (! m_bShowCursor)
rlm@1 264 {
rlm@1 265 vShowCursor();
rlm@1 266 }
rlm@1 267 vStartCursorTimeout();
rlm@1 268 return false;
rlm@1 269 }
rlm@1 270
rlm@1 271 bool ScreenArea::on_enter_notify_event(GdkEventCrossing * _pstEvent)
rlm@1 272 {
rlm@1 273 vStartCursorTimeout();
rlm@1 274 return false;
rlm@1 275 }
rlm@1 276
rlm@1 277 bool ScreenArea::on_leave_notify_event(GdkEventCrossing * _pstEvent)
rlm@1 278 {
rlm@1 279 vStopCursorTimeout();
rlm@1 280 if (! m_bShowCursor)
rlm@1 281 {
rlm@1 282 vShowCursor();
rlm@1 283 }
rlm@1 284 return false;
rlm@1 285 }
rlm@1 286
rlm@1 287 bool ScreenArea::bOnCursorTimeout()
rlm@1 288 {
rlm@1 289 vHideCursor();
rlm@1 290 return false;
rlm@1 291 }
rlm@1 292
rlm@1 293 } // namespace VBA