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