rlm@1
|
1 // MapView.cpp : implementation file
|
rlm@1
|
2 //
|
rlm@1
|
3
|
rlm@1
|
4 #include "stdafx.h"
|
rlm@1
|
5 #include "resource.h"
|
rlm@1
|
6 #include "MapView.h"
|
rlm@1
|
7 #include "FileDlg.h"
|
rlm@1
|
8 #include "Reg.h"
|
rlm@1
|
9 #include "WinResUtil.h"
|
rlm@1
|
10 #include "VBA.h"
|
rlm@1
|
11
|
rlm@1
|
12 #include "../gba/GBAGlobals.h"
|
rlm@1
|
13 #include "../NLS.h"
|
rlm@1
|
14 #include "../common/Util.h"
|
rlm@1
|
15
|
rlm@1
|
16 extern "C" {
|
rlm@1
|
17 #include <png.h>
|
rlm@1
|
18 }
|
rlm@1
|
19
|
rlm@1
|
20 /////////////////////////////////////////////////////////////////////////////
|
rlm@1
|
21 // MapView dialog
|
rlm@1
|
22
|
rlm@1
|
23 MapView::MapView(CWnd*pParent /*=NULL*/)
|
rlm@1
|
24 : ResizeDlg(MapView::IDD, pParent)
|
rlm@1
|
25 {
|
rlm@1
|
26 //{{AFX_DATA_INIT(MapView)
|
rlm@1
|
27 //}}AFX_DATA_INIT
|
rlm@1
|
28 autoUpdate = false;
|
rlm@1
|
29
|
rlm@1
|
30 memset(&bmpInfo.bmiHeader, 0, sizeof(bmpInfo.bmiHeader));
|
rlm@1
|
31
|
rlm@1
|
32 bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader);
|
rlm@1
|
33 bmpInfo.bmiHeader.biWidth = 1024;
|
rlm@1
|
34 bmpInfo.bmiHeader.biHeight = -1024;
|
rlm@1
|
35 bmpInfo.bmiHeader.biPlanes = 1;
|
rlm@1
|
36 bmpInfo.bmiHeader.biBitCount = 24;
|
rlm@1
|
37 bmpInfo.bmiHeader.biCompression = BI_RGB;
|
rlm@1
|
38 data = (u8 *)calloc(1, 3 * 1024 * 1024);
|
rlm@1
|
39
|
rlm@1
|
40 mapView.setData(data);
|
rlm@1
|
41 mapView.setBmpInfo(&bmpInfo);
|
rlm@1
|
42
|
rlm@1
|
43 control = BG0CNT;
|
rlm@1
|
44
|
rlm@1
|
45 bg = 0;
|
rlm@1
|
46 frame = 0;
|
rlm@1
|
47 }
|
rlm@1
|
48
|
rlm@1
|
49 MapView::~MapView()
|
rlm@1
|
50 {
|
rlm@1
|
51 free(data);
|
rlm@1
|
52 data = NULL;
|
rlm@1
|
53 }
|
rlm@1
|
54
|
rlm@1
|
55 void MapView::DoDataExchange(CDataExchange*pDX)
|
rlm@1
|
56 {
|
rlm@1
|
57 CDialog::DoDataExchange(pDX);
|
rlm@1
|
58 //{{AFX_DATA_MAP(MapView)
|
rlm@1
|
59 DDX_Control(pDX, IDC_NUMCOLORS, m_numcolors);
|
rlm@1
|
60 DDX_Control(pDX, IDC_MODE, m_mode);
|
rlm@1
|
61 DDX_Control(pDX, IDC_OVERFLOW, m_overflow);
|
rlm@1
|
62 DDX_Control(pDX, IDC_MOSAIC, m_mosaic);
|
rlm@1
|
63 DDX_Control(pDX, IDC_PRIORITY, m_priority);
|
rlm@1
|
64 DDX_Control(pDX, IDC_DIM, m_dim);
|
rlm@1
|
65 DDX_Control(pDX, IDC_CHARBASE, m_charbase);
|
rlm@1
|
66 DDX_Control(pDX, IDC_MAPBASE, m_mapbase);
|
rlm@1
|
67 //}}AFX_DATA_MAP
|
rlm@1
|
68 DDX_Control(pDX, IDC_MAP_VIEW, mapView);
|
rlm@1
|
69 DDX_Control(pDX, IDC_MAP_VIEW_ZOOM, mapViewZoom);
|
rlm@1
|
70 DDX_Control(pDX, IDC_COLOR, color);
|
rlm@1
|
71 }
|
rlm@1
|
72
|
rlm@1
|
73 BEGIN_MESSAGE_MAP(MapView, CDialog)
|
rlm@1
|
74 //{{AFX_MSG_MAP(MapView)
|
rlm@1
|
75 ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
|
rlm@1
|
76 ON_BN_CLICKED(IDC_FRAME_0, OnFrame0)
|
rlm@1
|
77 ON_BN_CLICKED(IDC_FRAME_1, OnFrame1)
|
rlm@1
|
78 ON_BN_CLICKED(IDC_BG0, OnBg0)
|
rlm@1
|
79 ON_BN_CLICKED(IDC_BG1, OnBg1)
|
rlm@1
|
80 ON_BN_CLICKED(IDC_BG2, OnBg2)
|
rlm@1
|
81 ON_BN_CLICKED(IDC_BG3, OnBg3)
|
rlm@1
|
82 ON_BN_CLICKED(IDC_STRETCH, OnStretch)
|
rlm@1
|
83 ON_BN_CLICKED(IDC_AUTO_UPDATE, OnAutoUpdate)
|
rlm@1
|
84 ON_BN_CLICKED(IDC_CLOSE, OnClose)
|
rlm@1
|
85 ON_BN_CLICKED(IDC_SAVE, OnSave)
|
rlm@1
|
86 //}}AFX_MSG_MAP
|
rlm@1
|
87 ON_MESSAGE(WM_MAPINFO, OnMapInfo)
|
rlm@1
|
88 ON_MESSAGE(WM_COLINFO, OnColInfo)
|
rlm@1
|
89 END_MESSAGE_MAP()
|
rlm@1
|
90
|
rlm@1
|
91 /////////////////////////////////////////////////////////////////////////////
|
rlm@1
|
92 // MapView message handlers
|
rlm@1
|
93
|
rlm@1
|
94 void MapView::renderTextScreen(u16 control)
|
rlm@1
|
95 {
|
rlm@1
|
96 u16 *palette = (u16 *)paletteRAM;
|
rlm@1
|
97 u8 * charBase = &vram[((control >> 2) & 0x03) * 0x4000];
|
rlm@1
|
98 u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800];
|
rlm@1
|
99 u8 * bmp = data;
|
rlm@1
|
100
|
rlm@1
|
101 int sizeX = 256;
|
rlm@1
|
102 int sizeY = 256;
|
rlm@1
|
103 switch ((control >> 14) & 3)
|
rlm@1
|
104 {
|
rlm@1
|
105 case 0:
|
rlm@1
|
106 break;
|
rlm@1
|
107 case 1:
|
rlm@1
|
108 sizeX = 512;
|
rlm@1
|
109 break;
|
rlm@1
|
110 case 2:
|
rlm@1
|
111 sizeY = 512;
|
rlm@1
|
112 break;
|
rlm@1
|
113 case 3:
|
rlm@1
|
114 sizeX = 512;
|
rlm@1
|
115 sizeY = 512;
|
rlm@1
|
116 break;
|
rlm@1
|
117 }
|
rlm@1
|
118
|
rlm@1
|
119 w = sizeX;
|
rlm@1
|
120 h = sizeY;
|
rlm@1
|
121
|
rlm@1
|
122 if (control & 0x80)
|
rlm@1
|
123 {
|
rlm@1
|
124 for (int y = 0; y < sizeY; y++)
|
rlm@1
|
125 {
|
rlm@1
|
126 int yy = y & 255;
|
rlm@1
|
127
|
rlm@1
|
128 if (y == 256 && sizeY > 256)
|
rlm@1
|
129 {
|
rlm@1
|
130 screenBase += 0x400;
|
rlm@1
|
131 if (sizeX > 256)
|
rlm@1
|
132 screenBase += 0x400;
|
rlm@1
|
133 }
|
rlm@1
|
134 u16 *screenSource = screenBase + ((yy>>3)*32);
|
rlm@1
|
135
|
rlm@1
|
136 for (int x = 0; x < sizeX; x++)
|
rlm@1
|
137 {
|
rlm@1
|
138 u16 data = *screenSource;
|
rlm@1
|
139
|
rlm@1
|
140 int tile = data & 0x3FF;
|
rlm@1
|
141 int tileX = (x & 7);
|
rlm@1
|
142 int tileY = y & 7;
|
rlm@1
|
143
|
rlm@1
|
144 if (data & 0x0400)
|
rlm@1
|
145 tileX = 7 - tileX;
|
rlm@1
|
146 if (data & 0x0800)
|
rlm@1
|
147 tileY = 7 - tileY;
|
rlm@1
|
148
|
rlm@1
|
149 u8 c = charBase[tile * 64 + tileY * 8 + tileX];
|
rlm@1
|
150
|
rlm@1
|
151 u16 color = palette[c];
|
rlm@1
|
152
|
rlm@1
|
153 *bmp++ = ((color >> 10) & 0x1f) << 3;
|
rlm@1
|
154 *bmp++ = ((color >> 5) & 0x1f) << 3;
|
rlm@1
|
155 *bmp++ = (color & 0x1f) << 3;
|
rlm@1
|
156
|
rlm@1
|
157 if (data & 0x0400)
|
rlm@1
|
158 {
|
rlm@1
|
159 if (tileX == 0)
|
rlm@1
|
160 screenSource++;
|
rlm@1
|
161 }
|
rlm@1
|
162 else if (tileX == 7)
|
rlm@1
|
163 screenSource++;
|
rlm@1
|
164 if (x == 255 && sizeX > 256)
|
rlm@1
|
165 {
|
rlm@1
|
166 screenSource = screenBase + 0x400 + ((yy>>3)*32);
|
rlm@1
|
167 }
|
rlm@1
|
168 }
|
rlm@1
|
169 }
|
rlm@1
|
170 }
|
rlm@1
|
171 else
|
rlm@1
|
172 {
|
rlm@1
|
173 for (int y = 0; y < sizeY; y++)
|
rlm@1
|
174 {
|
rlm@1
|
175 int yy = y & 255;
|
rlm@1
|
176
|
rlm@1
|
177 if (y == 256 && sizeY > 256)
|
rlm@1
|
178 {
|
rlm@1
|
179 screenBase += 0x400;
|
rlm@1
|
180 if (sizeX > 256)
|
rlm@1
|
181 screenBase += 0x400;
|
rlm@1
|
182 }
|
rlm@1
|
183 u16 *screenSource = screenBase + ((yy>>3)*32);
|
rlm@1
|
184
|
rlm@1
|
185 for (int x = 0; x < sizeX; x++)
|
rlm@1
|
186 {
|
rlm@1
|
187 u16 data = *screenSource;
|
rlm@1
|
188
|
rlm@1
|
189 int tile = data & 0x3FF;
|
rlm@1
|
190 int tileX = (x & 7);
|
rlm@1
|
191 int tileY = y & 7;
|
rlm@1
|
192
|
rlm@1
|
193 if (data & 0x0400)
|
rlm@1
|
194 tileX = 7 - tileX;
|
rlm@1
|
195 if (data & 0x0800)
|
rlm@1
|
196 tileY = 7 - tileY;
|
rlm@1
|
197
|
rlm@1
|
198 u8 color = charBase[tile * 32 + tileY * 4 + (tileX>>1)];
|
rlm@1
|
199
|
rlm@1
|
200 if (tileX & 1)
|
rlm@1
|
201 {
|
rlm@1
|
202 color = (color >> 4);
|
rlm@1
|
203 }
|
rlm@1
|
204 else
|
rlm@1
|
205 {
|
rlm@1
|
206 color &= 0x0F;
|
rlm@1
|
207 }
|
rlm@1
|
208
|
rlm@1
|
209 int pal = (*screenSource>>8) & 0xF0;
|
rlm@1
|
210 u16 color2 = palette[pal + color];
|
rlm@1
|
211
|
rlm@1
|
212 *bmp++ = ((color2 >> 10) & 0x1f) << 3;
|
rlm@1
|
213 *bmp++ = ((color2 >> 5) & 0x1f) << 3;
|
rlm@1
|
214 *bmp++ = (color2 & 0x1f) << 3;
|
rlm@1
|
215
|
rlm@1
|
216 if (data & 0x0400)
|
rlm@1
|
217 {
|
rlm@1
|
218 if (tileX == 0)
|
rlm@1
|
219 screenSource++;
|
rlm@1
|
220 }
|
rlm@1
|
221 else if (tileX == 7)
|
rlm@1
|
222 screenSource++;
|
rlm@1
|
223
|
rlm@1
|
224 if (x == 255 && sizeX > 256)
|
rlm@1
|
225 {
|
rlm@1
|
226 screenSource = screenBase + 0x400 + ((yy>>3)*32);
|
rlm@1
|
227 }
|
rlm@1
|
228 }
|
rlm@1
|
229 }
|
rlm@1
|
230 }
|
rlm@1
|
231 /*
|
rlm@1
|
232 switch(bg) {
|
rlm@1
|
233 case 0:
|
rlm@1
|
234 renderView(BG0HOFS<<8, BG0VOFS<<8,
|
rlm@1
|
235 0x100, 0x000,
|
rlm@1
|
236 0x000, 0x100,
|
rlm@1
|
237 (sizeX -1) <<8,
|
rlm@1
|
238 (sizeY -1) << 8,
|
rlm@1
|
239 true);
|
rlm@1
|
240 break;
|
rlm@1
|
241 case 1:
|
rlm@1
|
242 renderView(BG1HOFS<<8, BG1VOFS<<8,
|
rlm@1
|
243 0x100, 0x000,
|
rlm@1
|
244 0x000, 0x100,
|
rlm@1
|
245 (sizeX -1) <<8,
|
rlm@1
|
246 (sizeY -1) << 8,
|
rlm@1
|
247 true);
|
rlm@1
|
248 break;
|
rlm@1
|
249 case 2:
|
rlm@1
|
250 renderView(BG2HOFS<<8, BG2VOFS<<8,
|
rlm@1
|
251 0x100, 0x000,
|
rlm@1
|
252 0x000, 0x100,
|
rlm@1
|
253 (sizeX -1) <<8,
|
rlm@1
|
254 (sizeY -1) << 8,
|
rlm@1
|
255 true);
|
rlm@1
|
256 break;
|
rlm@1
|
257 case 3:
|
rlm@1
|
258 renderView(BG3HOFS<<8, BG3VOFS<<8,
|
rlm@1
|
259 0x100, 0x000,
|
rlm@1
|
260 0x000, 0x100,
|
rlm@1
|
261 (sizeX -1) <<8,
|
rlm@1
|
262 (sizeY -1) << 8,
|
rlm@1
|
263 true);
|
rlm@1
|
264 break;
|
rlm@1
|
265 }
|
rlm@1
|
266 */
|
rlm@1
|
267 }
|
rlm@1
|
268
|
rlm@1
|
269 void MapView::renderRotScreen(u16 control)
|
rlm@1
|
270 {
|
rlm@1
|
271 u16 *palette = (u16 *)paletteRAM;
|
rlm@1
|
272 u8 * charBase = &vram[((control >> 2) & 0x03) * 0x4000];
|
rlm@1
|
273 u8 * screenBase = (u8 *)&vram[((control >> 8) & 0x1f) * 0x800];
|
rlm@1
|
274 u8 * bmp = data;
|
rlm@1
|
275
|
rlm@1
|
276 int sizeX = 128;
|
rlm@1
|
277 int sizeY = 128;
|
rlm@1
|
278 switch ((control >> 14) & 3)
|
rlm@1
|
279 {
|
rlm@1
|
280 case 0:
|
rlm@1
|
281 break;
|
rlm@1
|
282 case 1:
|
rlm@1
|
283 sizeX = sizeY = 256;
|
rlm@1
|
284 break;
|
rlm@1
|
285 case 2:
|
rlm@1
|
286 sizeX = sizeY = 512;
|
rlm@1
|
287 break;
|
rlm@1
|
288 case 3:
|
rlm@1
|
289 sizeX = sizeY = 1024;
|
rlm@1
|
290 break;
|
rlm@1
|
291 }
|
rlm@1
|
292
|
rlm@1
|
293 w = sizeX;
|
rlm@1
|
294 h = sizeY;
|
rlm@1
|
295
|
rlm@1
|
296 if (control & 0x80)
|
rlm@1
|
297 {
|
rlm@1
|
298 for (int y = 0; y < sizeY; y++)
|
rlm@1
|
299 {
|
rlm@1
|
300 for (int x = 0; x < sizeX; x++)
|
rlm@1
|
301 {
|
rlm@1
|
302 int tile = screenBase[(x>>3) + (y>>3)*(w>>3)];
|
rlm@1
|
303
|
rlm@1
|
304 int tileX = (x & 7);
|
rlm@1
|
305 int tileY = y & 7;
|
rlm@1
|
306
|
rlm@1
|
307 u8 color = charBase[tile * 64 + tileY * 8 + tileX];
|
rlm@1
|
308 u16 color2 = palette[color];
|
rlm@1
|
309
|
rlm@1
|
310 *bmp++ = ((color2 >> 10) & 0x1f) << 3;
|
rlm@1
|
311 *bmp++ = ((color2 >> 5) & 0x1f) << 3;
|
rlm@1
|
312 *bmp++ = (color2 & 0x1f) << 3;
|
rlm@1
|
313 }
|
rlm@1
|
314 }
|
rlm@1
|
315 }
|
rlm@1
|
316 else
|
rlm@1
|
317 {
|
rlm@1
|
318 for (int y = 0; y < sizeY; y++)
|
rlm@1
|
319 {
|
rlm@1
|
320 for (int x = 0; x < sizeX; x++)
|
rlm@1
|
321 {
|
rlm@1
|
322 int tile = screenBase[(x>>3) + (y>>3)*(w>>3)];
|
rlm@1
|
323
|
rlm@1
|
324 int tileX = (x & 7);
|
rlm@1
|
325 int tileY = y & 7;
|
rlm@1
|
326
|
rlm@1
|
327 u8 color = charBase[tile * 64 + tileY * 8 + tileX];
|
rlm@1
|
328 u16 color2 = palette[color];
|
rlm@1
|
329
|
rlm@1
|
330 *bmp++ = ((color2 >> 10) & 0x1f) << 3;
|
rlm@1
|
331 *bmp++ = ((color2 >> 5) & 0x1f) << 3;
|
rlm@1
|
332 *bmp++ = (color2 & 0x1f) << 3;
|
rlm@1
|
333 }
|
rlm@1
|
334 }
|
rlm@1
|
335 }
|
rlm@1
|
336
|
rlm@1
|
337 u32 xx;
|
rlm@1
|
338 u32 yy;
|
rlm@1
|
339
|
rlm@1
|
340 switch (bg)
|
rlm@1
|
341 {
|
rlm@1
|
342 case 2:
|
rlm@1
|
343 xx = BG2X_L | BG2X_H << 16;
|
rlm@1
|
344 yy = BG2Y_L | BG2Y_H << 16;
|
rlm@1
|
345
|
rlm@1
|
346 /*
|
rlm@1
|
347 renderView(xx, yy,
|
rlm@1
|
348 BG2PA, BG2PC,
|
rlm@1
|
349 BG2PB, BG2PD,
|
rlm@1
|
350 (sizeX -1) <<8,
|
rlm@1
|
351 (sizeY -1) << 8,
|
rlm@1
|
352 (control & 0x2000) != 0);
|
rlm@1
|
353 */
|
rlm@1
|
354 break;
|
rlm@1
|
355 case 3:
|
rlm@1
|
356 xx = BG3X_L | BG3X_H << 16;
|
rlm@1
|
357 yy = BG3Y_L | BG3Y_H << 16;
|
rlm@1
|
358 /*
|
rlm@1
|
359 renderView(xx, yy,
|
rlm@1
|
360 BG3PA, BG3PC,
|
rlm@1
|
361 BG3PB, BG3PD,
|
rlm@1
|
362 (sizeX -1) <<8,
|
rlm@1
|
363 (sizeY -1) << 8,
|
rlm@1
|
364 (control & 0x2000) != 0);
|
rlm@1
|
365 */
|
rlm@1
|
366 break;
|
rlm@1
|
367 }
|
rlm@1
|
368 }
|
rlm@1
|
369
|
rlm@1
|
370 void MapView::renderMode0()
|
rlm@1
|
371 {
|
rlm@1
|
372 renderTextScreen(control);
|
rlm@1
|
373 }
|
rlm@1
|
374
|
rlm@1
|
375 void MapView::renderMode1()
|
rlm@1
|
376 {
|
rlm@1
|
377 switch (bg)
|
rlm@1
|
378 {
|
rlm@1
|
379 case 0:
|
rlm@1
|
380 case 1:
|
rlm@1
|
381 renderTextScreen(control);
|
rlm@1
|
382 break;
|
rlm@1
|
383 case 2:
|
rlm@1
|
384 renderRotScreen(control);
|
rlm@1
|
385 break;
|
rlm@1
|
386 default:
|
rlm@1
|
387 bg = 0;
|
rlm@1
|
388 control = BG0CNT;
|
rlm@1
|
389 renderTextScreen(control);
|
rlm@1
|
390 break;
|
rlm@1
|
391 }
|
rlm@1
|
392 }
|
rlm@1
|
393
|
rlm@1
|
394 void MapView::renderMode2()
|
rlm@1
|
395 {
|
rlm@1
|
396 switch (bg)
|
rlm@1
|
397 {
|
rlm@1
|
398 case 2:
|
rlm@1
|
399 case 3:
|
rlm@1
|
400 renderRotScreen(control);
|
rlm@1
|
401 break;
|
rlm@1
|
402 default:
|
rlm@1
|
403 bg = 2;
|
rlm@1
|
404 control = BG2CNT;
|
rlm@1
|
405 renderRotScreen(control);
|
rlm@1
|
406 break;
|
rlm@1
|
407 }
|
rlm@1
|
408 }
|
rlm@1
|
409
|
rlm@1
|
410 void MapView::renderMode3()
|
rlm@1
|
411 {
|
rlm@1
|
412 u8 * bmp = data;
|
rlm@1
|
413 u16 *src = (u16 *)&vram[0];
|
rlm@1
|
414
|
rlm@1
|
415 w = 240;
|
rlm@1
|
416 h = 160;
|
rlm@1
|
417
|
rlm@1
|
418 for (int y = 0; y < 160; y++)
|
rlm@1
|
419 {
|
rlm@1
|
420 for (int x = 0; x < 240; x++)
|
rlm@1
|
421 {
|
rlm@1
|
422 u16 data = *src++;
|
rlm@1
|
423 *bmp++ = ((data >> 10) & 0x1f) << 3;
|
rlm@1
|
424 *bmp++ = ((data >> 5) & 0x1f) << 3;
|
rlm@1
|
425 *bmp++ = (data & 0x1f) << 3;
|
rlm@1
|
426 }
|
rlm@1
|
427 }
|
rlm@1
|
428 bg = 2;
|
rlm@1
|
429 }
|
rlm@1
|
430
|
rlm@1
|
431 void MapView::renderMode4()
|
rlm@1
|
432 {
|
rlm@1
|
433 u8 * bmp = data;
|
rlm@1
|
434 u8 * src = frame ? &vram[0xa000] : &vram[0];
|
rlm@1
|
435 u16 *pal = (u16 *)&paletteRAM[0];
|
rlm@1
|
436
|
rlm@1
|
437 w = 240;
|
rlm@1
|
438 h = 160;
|
rlm@1
|
439
|
rlm@1
|
440 for (int y = 0; y < 160; y++)
|
rlm@1
|
441 {
|
rlm@1
|
442 for (int x = 0; x < 240; x++)
|
rlm@1
|
443 {
|
rlm@1
|
444 u8 c = *src++;
|
rlm@1
|
445 u16 data = pal[c];
|
rlm@1
|
446 *bmp++ = ((data >> 10) & 0x1f) << 3;
|
rlm@1
|
447 *bmp++ = ((data >> 5) & 0x1f) << 3;
|
rlm@1
|
448 *bmp++ = (data & 0x1f) << 3;
|
rlm@1
|
449 }
|
rlm@1
|
450 }
|
rlm@1
|
451 bg = 2;
|
rlm@1
|
452 }
|
rlm@1
|
453
|
rlm@1
|
454 void MapView::renderMode5()
|
rlm@1
|
455 {
|
rlm@1
|
456 u8 * bmp = data;
|
rlm@1
|
457 u16 *src = (u16 *)(frame ? &vram[0xa000] : &vram[0]);
|
rlm@1
|
458
|
rlm@1
|
459 w = 160;
|
rlm@1
|
460 h = 128;
|
rlm@1
|
461
|
rlm@1
|
462 for (int y = 0; y < 128; y++)
|
rlm@1
|
463 {
|
rlm@1
|
464 for (int x = 0; x < 160; x++)
|
rlm@1
|
465 {
|
rlm@1
|
466 u16 data = *src++;
|
rlm@1
|
467 *bmp++ = ((data >> 10) & 0x1f) << 3;
|
rlm@1
|
468 *bmp++ = ((data >> 5) & 0x1f) << 3;
|
rlm@1
|
469 *bmp++ = (data & 0x1f) << 3;
|
rlm@1
|
470 }
|
rlm@1
|
471 }
|
rlm@1
|
472 bg = 2;
|
rlm@1
|
473 }
|
rlm@1
|
474
|
rlm@1
|
475 void MapView::OnRefresh()
|
rlm@1
|
476 {
|
rlm@1
|
477 paint();
|
rlm@1
|
478 }
|
rlm@1
|
479
|
rlm@1
|
480 void MapView::paint()
|
rlm@1
|
481 {
|
rlm@1
|
482 if (vram == NULL)
|
rlm@1
|
483 return;
|
rlm@1
|
484 int mode = DISPCNT & 7;
|
rlm@1
|
485
|
rlm@1
|
486 switch (bg)
|
rlm@1
|
487 {
|
rlm@1
|
488 default:
|
rlm@1
|
489 case 0:
|
rlm@1
|
490 control = BG0CNT;
|
rlm@1
|
491 break;
|
rlm@1
|
492 case 1:
|
rlm@1
|
493 control = BG1CNT;
|
rlm@1
|
494 break;
|
rlm@1
|
495 case 2:
|
rlm@1
|
496 control = BG2CNT;
|
rlm@1
|
497 break;
|
rlm@1
|
498 case 3:
|
rlm@1
|
499 control = BG3CNT;
|
rlm@1
|
500 break;
|
rlm@1
|
501 }
|
rlm@1
|
502
|
rlm@1
|
503 switch (mode)
|
rlm@1
|
504 {
|
rlm@1
|
505 case 0:
|
rlm@1
|
506 renderMode0();
|
rlm@1
|
507 break;
|
rlm@1
|
508 case 1:
|
rlm@1
|
509 renderMode1();
|
rlm@1
|
510 break;
|
rlm@1
|
511 case 2:
|
rlm@1
|
512 renderMode2();
|
rlm@1
|
513 break;
|
rlm@1
|
514 case 3:
|
rlm@1
|
515 renderMode3();
|
rlm@1
|
516 break;
|
rlm@1
|
517 case 4:
|
rlm@1
|
518 renderMode4();
|
rlm@1
|
519 break;
|
rlm@1
|
520 case 5:
|
rlm@1
|
521 renderMode5();
|
rlm@1
|
522 break;
|
rlm@1
|
523 }
|
rlm@1
|
524 enableButtons(mode);
|
rlm@1
|
525 SIZE s;
|
rlm@1
|
526
|
rlm@1
|
527 if (mapView.getStretch())
|
rlm@1
|
528 {
|
rlm@1
|
529 mapView.setSize(w, h);
|
rlm@1
|
530 s.cx = s.cy = 1;
|
rlm@1
|
531 mapView.SetScrollSizes(MM_TEXT, s);
|
rlm@1
|
532 }
|
rlm@1
|
533 else
|
rlm@1
|
534 {
|
rlm@1
|
535 mapView.setSize(w, h);
|
rlm@1
|
536 s.cx = w;
|
rlm@1
|
537 s.cy = h;
|
rlm@1
|
538 mapView.SetScrollSizes(MM_TEXT, s);
|
rlm@1
|
539 }
|
rlm@1
|
540
|
rlm@1
|
541 mapView.refresh();
|
rlm@1
|
542
|
rlm@1
|
543 CString buffer;
|
rlm@1
|
544
|
rlm@1
|
545 u32 charBase = ((control >> 2) & 0x03) * 0x4000 + 0x6000000;
|
rlm@1
|
546 u32 screenBase = ((control >> 8) & 0x1f) * 0x800 + 0x6000000;
|
rlm@1
|
547
|
rlm@1
|
548 buffer.Format("%d", mode);
|
rlm@1
|
549 m_mode.SetWindowText(buffer);
|
rlm@1
|
550
|
rlm@1
|
551 if (mode >= 3)
|
rlm@1
|
552 {
|
rlm@1
|
553 m_mapbase.SetWindowText("");
|
rlm@1
|
554 m_charbase.SetWindowText("");
|
rlm@1
|
555 }
|
rlm@1
|
556 else
|
rlm@1
|
557 {
|
rlm@1
|
558 buffer.Format("0x%08X", screenBase);
|
rlm@1
|
559 m_mapbase.SetWindowText(buffer);
|
rlm@1
|
560
|
rlm@1
|
561 buffer.Format("0x%08X", charBase);
|
rlm@1
|
562 m_charbase.SetWindowText(buffer);
|
rlm@1
|
563 }
|
rlm@1
|
564
|
rlm@1
|
565 buffer.Format("%dx%d", w, h);
|
rlm@1
|
566 m_dim.SetWindowText(buffer);
|
rlm@1
|
567
|
rlm@1
|
568 m_numcolors.SetWindowText(control & 0x80 ? "256" : "16");
|
rlm@1
|
569
|
rlm@1
|
570 buffer.Format("%d", control & 3);
|
rlm@1
|
571 m_priority.SetWindowText(buffer);
|
rlm@1
|
572
|
rlm@1
|
573 m_mosaic.SetWindowText(control & 0x40 ? "1" : "0");
|
rlm@1
|
574
|
rlm@1
|
575 m_overflow.SetWindowText(bg <= 1 ? "" :
|
rlm@1
|
576 control & 0x2000 ? "1" : "0");
|
rlm@1
|
577 }
|
rlm@1
|
578
|
rlm@1
|
579 BOOL MapView::OnInitDialog()
|
rlm@1
|
580 {
|
rlm@1
|
581 CDialog::OnInitDialog();
|
rlm@1
|
582
|
rlm@1
|
583 DIALOG_SIZER_START(sz)
|
rlm@1
|
584 DIALOG_SIZER_ENTRY(IDC_MAP_VIEW, DS_SizeX | DS_SizeY)
|
rlm@1
|
585 DIALOG_SIZER_ENTRY(IDC_REFRESH, DS_MoveY)
|
rlm@1
|
586 DIALOG_SIZER_ENTRY(IDC_CLOSE, DS_MoveY)
|
rlm@1
|
587 DIALOG_SIZER_ENTRY(IDC_SAVE, DS_MoveY)
|
rlm@1
|
588 DIALOG_SIZER_ENTRY(IDC_COLOR, DS_MoveY)
|
rlm@1
|
589 DIALOG_SIZER_ENTRY(IDC_R, DS_MoveY)
|
rlm@1
|
590 DIALOG_SIZER_ENTRY(IDC_G, DS_MoveY)
|
rlm@1
|
591 DIALOG_SIZER_ENTRY(IDC_B, DS_MoveY)
|
rlm@1
|
592 DIALOG_SIZER_END()
|
rlm@1
|
593 SetData(sz,
|
rlm@1
|
594 TRUE,
|
rlm@1
|
595 HKEY_CURRENT_USER,
|
rlm@1
|
596 "Software\\Emulators\\VisualBoyAdvance\\Viewer\\MapView",
|
rlm@1
|
597 NULL);
|
rlm@1
|
598
|
rlm@1
|
599 SIZE size;
|
rlm@1
|
600 size.cx = 1;
|
rlm@1
|
601 size.cy = 1;
|
rlm@1
|
602 mapView.SetScrollSizes(MM_TEXT, size);
|
rlm@1
|
603 int s = regQueryDwordValue("mapViewStretch", 0);
|
rlm@1
|
604 if (s)
|
rlm@1
|
605 mapView.setStretch(true);
|
rlm@1
|
606 ((CButton *)GetDlgItem(IDC_STRETCH))->SetCheck(s);
|
rlm@1
|
607 paint();
|
rlm@1
|
608
|
rlm@1
|
609 return TRUE; // return TRUE unless you set the focus to a control
|
rlm@1
|
610 // EXCEPTION: OCX Property Pages should return FALSE
|
rlm@1
|
611 }
|
rlm@1
|
612
|
rlm@1
|
613 void MapView::PostNcDestroy()
|
rlm@1
|
614 {
|
rlm@1
|
615 delete this;
|
rlm@1
|
616 }
|
rlm@1
|
617
|
rlm@1
|
618 void MapView::enableButtons(int mode)
|
rlm@1
|
619 {
|
rlm@1
|
620 bool enable[6] = { true, true, true, true, true, true };
|
rlm@1
|
621
|
rlm@1
|
622 switch (mode)
|
rlm@1
|
623 {
|
rlm@1
|
624 case 0:
|
rlm@1
|
625 enable[4] = false;
|
rlm@1
|
626 enable[5] = false;
|
rlm@1
|
627 break;
|
rlm@1
|
628 case 1:
|
rlm@1
|
629 enable[3] = false;
|
rlm@1
|
630 enable[4] = false;
|
rlm@1
|
631 enable[5] = false;
|
rlm@1
|
632 break;
|
rlm@1
|
633 case 2:
|
rlm@1
|
634 enable[0] = false;
|
rlm@1
|
635 enable[1] = false;
|
rlm@1
|
636 enable[4] = false;
|
rlm@1
|
637 enable[5] = false;
|
rlm@1
|
638 break;
|
rlm@1
|
639 case 3:
|
rlm@1
|
640 enable[0] = false;
|
rlm@1
|
641 enable[1] = false;
|
rlm@1
|
642 enable[2] = false;
|
rlm@1
|
643 enable[3] = false;
|
rlm@1
|
644 enable[4] = false;
|
rlm@1
|
645 enable[5] = false;
|
rlm@1
|
646 break;
|
rlm@1
|
647 case 4:
|
rlm@1
|
648 enable[0] = false;
|
rlm@1
|
649 enable[1] = false;
|
rlm@1
|
650 enable[2] = false;
|
rlm@1
|
651 enable[3] = false;
|
rlm@1
|
652 break;
|
rlm@1
|
653 case 5:
|
rlm@1
|
654 enable[0] = false;
|
rlm@1
|
655 enable[1] = false;
|
rlm@1
|
656 enable[2] = false;
|
rlm@1
|
657 enable[3] = false;
|
rlm@1
|
658 break;
|
rlm@1
|
659 }
|
rlm@1
|
660 GetDlgItem(IDC_BG0)->EnableWindow(enable[0]);
|
rlm@1
|
661 GetDlgItem(IDC_BG1)->EnableWindow(enable[1]);
|
rlm@1
|
662 GetDlgItem(IDC_BG2)->EnableWindow(enable[2]);
|
rlm@1
|
663 GetDlgItem(IDC_BG3)->EnableWindow(enable[3]);
|
rlm@1
|
664 GetDlgItem(IDC_FRAME_0)->EnableWindow(enable[4]);
|
rlm@1
|
665 GetDlgItem(IDC_FRAME_1)->EnableWindow(enable[5]);
|
rlm@1
|
666 int id = IDC_BG0;
|
rlm@1
|
667 switch (bg)
|
rlm@1
|
668 {
|
rlm@1
|
669 case 1:
|
rlm@1
|
670 id = IDC_BG1;
|
rlm@1
|
671 break;
|
rlm@1
|
672 case 2:
|
rlm@1
|
673 id = IDC_BG2;
|
rlm@1
|
674 break;
|
rlm@1
|
675 case 3:
|
rlm@1
|
676 id = IDC_BG3;
|
rlm@1
|
677 break;
|
rlm@1
|
678 }
|
rlm@1
|
679 CheckRadioButton(IDC_BG0, IDC_BG3, id);
|
rlm@1
|
680 id = IDC_FRAME_0;
|
rlm@1
|
681 if (frame != 0)
|
rlm@1
|
682 id = IDC_FRAME_1;
|
rlm@1
|
683 CheckRadioButton(IDC_FRAME_0, IDC_FRAME_1, id);
|
rlm@1
|
684 }
|
rlm@1
|
685
|
rlm@1
|
686 void MapView::OnFrame0()
|
rlm@1
|
687 {
|
rlm@1
|
688 frame = 0;
|
rlm@1
|
689 paint();
|
rlm@1
|
690 }
|
rlm@1
|
691
|
rlm@1
|
692 void MapView::OnFrame1()
|
rlm@1
|
693 {
|
rlm@1
|
694 frame = 1;
|
rlm@1
|
695 paint();
|
rlm@1
|
696 }
|
rlm@1
|
697
|
rlm@1
|
698 void MapView::OnBg0()
|
rlm@1
|
699 {
|
rlm@1
|
700 bg = 0;
|
rlm@1
|
701 control = BG0CNT;
|
rlm@1
|
702 paint();
|
rlm@1
|
703 }
|
rlm@1
|
704
|
rlm@1
|
705 void MapView::OnBg1()
|
rlm@1
|
706 {
|
rlm@1
|
707 bg = 1;
|
rlm@1
|
708 control = BG1CNT;
|
rlm@1
|
709 paint();
|
rlm@1
|
710 }
|
rlm@1
|
711
|
rlm@1
|
712 void MapView::OnBg2()
|
rlm@1
|
713 {
|
rlm@1
|
714 bg = 2;
|
rlm@1
|
715 control = BG2CNT;
|
rlm@1
|
716 paint();
|
rlm@1
|
717 }
|
rlm@1
|
718
|
rlm@1
|
719 void MapView::OnBg3()
|
rlm@1
|
720 {
|
rlm@1
|
721 bg = 3;
|
rlm@1
|
722 control = BG3CNT;
|
rlm@1
|
723 paint();
|
rlm@1
|
724 }
|
rlm@1
|
725
|
rlm@1
|
726 void MapView::OnStretch()
|
rlm@1
|
727 {
|
rlm@1
|
728 mapView.setStretch(!mapView.getStretch());
|
rlm@1
|
729 paint();
|
rlm@1
|
730 regSetDwordValue("mapViewStretch", mapView.getStretch());
|
rlm@1
|
731 }
|
rlm@1
|
732
|
rlm@1
|
733 void MapView::OnAutoUpdate()
|
rlm@1
|
734 {
|
rlm@1
|
735 autoUpdate = !autoUpdate;
|
rlm@1
|
736 if (autoUpdate)
|
rlm@1
|
737 {
|
rlm@1
|
738 theApp.winAddUpdateListener(this);
|
rlm@1
|
739 }
|
rlm@1
|
740 else
|
rlm@1
|
741 {
|
rlm@1
|
742 theApp.winRemoveUpdateListener(this);
|
rlm@1
|
743 }
|
rlm@1
|
744 }
|
rlm@1
|
745
|
rlm@1
|
746 void MapView::update()
|
rlm@1
|
747 {
|
rlm@1
|
748 paint();
|
rlm@1
|
749 }
|
rlm@1
|
750
|
rlm@1
|
751 void MapView::OnClose()
|
rlm@1
|
752 {
|
rlm@1
|
753 theApp.winRemoveUpdateListener(this);
|
rlm@1
|
754
|
rlm@1
|
755 DestroyWindow();
|
rlm@1
|
756 }
|
rlm@1
|
757
|
rlm@1
|
758 u32 MapView::GetTextClickAddress(u32 base, int x, int y)
|
rlm@1
|
759 {
|
rlm@1
|
760 if (y > 255 && h > 256)
|
rlm@1
|
761 {
|
rlm@1
|
762 base += 0x800;
|
rlm@1
|
763 if (w > 256)
|
rlm@1
|
764 base += 0x800;
|
rlm@1
|
765 }
|
rlm@1
|
766 if (x >= 256)
|
rlm@1
|
767 base += 0x800;
|
rlm@1
|
768 x &= 255;
|
rlm@1
|
769 y &= 255;
|
rlm@1
|
770 base += (x>>3)*2 + 64*(y>>3);
|
rlm@1
|
771
|
rlm@1
|
772 return base;
|
rlm@1
|
773 }
|
rlm@1
|
774
|
rlm@1
|
775 u32 MapView::GetClickAddress(int x, int y)
|
rlm@1
|
776 {
|
rlm@1
|
777 int mode = DISPCNT & 7;
|
rlm@1
|
778
|
rlm@1
|
779 u32 base = ((control >> 8) & 0x1f) * 0x800 + 0x6000000;
|
rlm@1
|
780
|
rlm@1
|
781 // all text bgs (16 bits)
|
rlm@1
|
782 if (mode == 0 || (mode < 3 && bg < 2))
|
rlm@1
|
783 {
|
rlm@1
|
784 return GetTextClickAddress(base, x, y);
|
rlm@1
|
785 }
|
rlm@1
|
786 // rot bgs (8 bits)
|
rlm@1
|
787 if (mode < 3)
|
rlm@1
|
788 {
|
rlm@1
|
789 return base + (x>>3) + (w>>3)*(y>>3);
|
rlm@1
|
790 }
|
rlm@1
|
791 // mode 3/5 (16 bits)
|
rlm@1
|
792 if (mode != 4)
|
rlm@1
|
793 {
|
rlm@1
|
794 return 0x6000000 + 0xa000*frame + 2*x + w*y*2;
|
rlm@1
|
795 }
|
rlm@1
|
796 // mode 4 (8 bits)
|
rlm@1
|
797 return 0x6000000 + 0xa000*frame + x + w*y;
|
rlm@1
|
798 }
|
rlm@1
|
799
|
rlm@1
|
800 LRESULT MapView::OnMapInfo(WPARAM wParam, LPARAM lParam)
|
rlm@1
|
801 {
|
rlm@1
|
802 u8 *colors = (u8 *)lParam;
|
rlm@1
|
803 mapViewZoom.setColors(colors);
|
rlm@1
|
804
|
rlm@1
|
805 int x = wParam & 0xffff;
|
rlm@1
|
806 int y = (wParam >> 16);
|
rlm@1
|
807
|
rlm@1
|
808 CString buffer;
|
rlm@1
|
809 buffer.Format("(%d,%d)", x, y);
|
rlm@1
|
810 GetDlgItem(IDC_XY)->SetWindowText(buffer);
|
rlm@1
|
811
|
rlm@1
|
812 u32 address = GetClickAddress(x, y);
|
rlm@1
|
813 buffer.Format("0x%08X", address);
|
rlm@1
|
814 GetDlgItem(IDC_ADDRESS)->SetWindowText(buffer);
|
rlm@1
|
815
|
rlm@1
|
816 int mode = DISPCNT & 7;
|
rlm@1
|
817 if (mode >= 3)
|
rlm@1
|
818 {
|
rlm@1
|
819 // bitmap modes
|
rlm@1
|
820 GetDlgItem(IDC_TILE_NUM)->SetWindowText("---");
|
rlm@1
|
821 GetDlgItem(IDC_FLIP)->SetWindowText("--");
|
rlm@1
|
822 GetDlgItem(IDC_PALETTE_NUM)->SetWindowText("---");
|
rlm@1
|
823 }
|
rlm@1
|
824 else if (mode == 0 || bg < 2)
|
rlm@1
|
825 {
|
rlm@1
|
826 // text bgs
|
rlm@1
|
827 u16 value = *((u16 *)&vram[address - 0x6000000]);
|
rlm@1
|
828
|
rlm@1
|
829 int tile = value & 1023;
|
rlm@1
|
830 buffer.Format("%d", tile);
|
rlm@1
|
831 GetDlgItem(IDC_TILE_NUM)->SetWindowText(buffer);
|
rlm@1
|
832 buffer.Empty();
|
rlm@1
|
833 buffer += value & 1024 ? 'H' : '-';
|
rlm@1
|
834 buffer += value & 2048 ? 'V' : '-';
|
rlm@1
|
835 GetDlgItem(IDC_FLIP)->SetWindowText(buffer);
|
rlm@1
|
836
|
rlm@1
|
837 if (!(control & 0x80))
|
rlm@1
|
838 {
|
rlm@1
|
839 buffer.Format("%d", (value >> 12) & 15);
|
rlm@1
|
840 }
|
rlm@1
|
841 else
|
rlm@1
|
842 buffer = "---";
|
rlm@1
|
843 GetDlgItem(IDC_PALETTE_NUM)->SetWindowText(buffer);
|
rlm@1
|
844 }
|
rlm@1
|
845 else
|
rlm@1
|
846 {
|
rlm@1
|
847 // rot bgs
|
rlm@1
|
848 GetDlgItem(IDC_TILE_NUM)->SetWindowText("---");
|
rlm@1
|
849 GetDlgItem(IDC_FLIP)->SetWindowText("--");
|
rlm@1
|
850 GetDlgItem(IDC_PALETTE_NUM)->SetWindowText("---");
|
rlm@1
|
851 }
|
rlm@1
|
852
|
rlm@1
|
853 return TRUE;
|
rlm@1
|
854 }
|
rlm@1
|
855
|
rlm@1
|
856 LRESULT MapView::OnColInfo(WPARAM wParam, LPARAM lParam)
|
rlm@1
|
857 {
|
rlm@1
|
858 u16 c = (u16)wParam;
|
rlm@1
|
859
|
rlm@1
|
860 color.setColor(c);
|
rlm@1
|
861
|
rlm@1
|
862 int r = (c & 0x1f);
|
rlm@1
|
863 int g = (c & 0x3e0) >> 5;
|
rlm@1
|
864 int b = (c & 0x7c00) >> 10;
|
rlm@1
|
865
|
rlm@1
|
866 CString buffer;
|
rlm@1
|
867 buffer.Format("R: %d", r);
|
rlm@1
|
868 GetDlgItem(IDC_R)->SetWindowText(buffer);
|
rlm@1
|
869
|
rlm@1
|
870 buffer.Format("G: %d", g);
|
rlm@1
|
871 GetDlgItem(IDC_G)->SetWindowText(buffer);
|
rlm@1
|
872
|
rlm@1
|
873 buffer.Format("B: %d", b);
|
rlm@1
|
874 GetDlgItem(IDC_B)->SetWindowText(buffer);
|
rlm@1
|
875
|
rlm@1
|
876 return TRUE;
|
rlm@1
|
877 }
|
rlm@1
|
878
|
rlm@1
|
879 void MapView::saveBMP(const char *name)
|
rlm@1
|
880 {
|
rlm@1
|
881 u8 writeBuffer[1024 * 3];
|
rlm@1
|
882
|
rlm@1
|
883 FILE *fp = fopen(name, "wb");
|
rlm@1
|
884
|
rlm@1
|
885 if (!fp)
|
rlm@1
|
886 {
|
rlm@1
|
887 systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s", name);
|
rlm@1
|
888 return;
|
rlm@1
|
889 }
|
rlm@1
|
890
|
rlm@1
|
891 struct
|
rlm@1
|
892 {
|
rlm@1
|
893 u8 ident[2];
|
rlm@1
|
894 u8 filesize[4];
|
rlm@1
|
895 u8 reserved[4];
|
rlm@1
|
896 u8 dataoffset[4];
|
rlm@1
|
897 u8 headersize[4];
|
rlm@1
|
898 u8 width[4];
|
rlm@1
|
899 u8 height[4];
|
rlm@1
|
900 u8 planes[2];
|
rlm@1
|
901 u8 bitsperpixel[2];
|
rlm@1
|
902 u8 compression[4];
|
rlm@1
|
903 u8 datasize[4];
|
rlm@1
|
904 u8 hres[4];
|
rlm@1
|
905 u8 vres[4];
|
rlm@1
|
906 u8 colors[4];
|
rlm@1
|
907 u8 importantcolors[4];
|
rlm@1
|
908 u8 pad[2];
|
rlm@1
|
909 } bmpheader;
|
rlm@1
|
910 memset(&bmpheader, 0, sizeof(bmpheader));
|
rlm@1
|
911
|
rlm@1
|
912 bmpheader.ident[0] = 'B';
|
rlm@1
|
913 bmpheader.ident[1] = 'M';
|
rlm@1
|
914
|
rlm@1
|
915 u32 fsz = sizeof(bmpheader) + w*h*3;
|
rlm@1
|
916 utilPutDword(bmpheader.filesize, fsz);
|
rlm@1
|
917 utilPutDword(bmpheader.dataoffset, 0x38);
|
rlm@1
|
918 utilPutDword(bmpheader.headersize, 0x28);
|
rlm@1
|
919 utilPutDword(bmpheader.width, w);
|
rlm@1
|
920 utilPutDword(bmpheader.height, h);
|
rlm@1
|
921 utilPutDword(bmpheader.planes, 1);
|
rlm@1
|
922 utilPutDword(bmpheader.bitsperpixel, 24);
|
rlm@1
|
923 utilPutDword(bmpheader.datasize, 3*w*h);
|
rlm@1
|
924
|
rlm@1
|
925 fwrite(&bmpheader, 1, sizeof(bmpheader), fp);
|
rlm@1
|
926
|
rlm@1
|
927 u8 *b = writeBuffer;
|
rlm@1
|
928
|
rlm@1
|
929 int sizeX = w;
|
rlm@1
|
930 int sizeY = h;
|
rlm@1
|
931
|
rlm@1
|
932 u8 *pixU8 = (u8 *)data+3*w*(h-1);
|
rlm@1
|
933 for (int y = 0; y < sizeY; y++)
|
rlm@1
|
934 {
|
rlm@1
|
935 for (int x = 0; x < sizeX; x++)
|
rlm@1
|
936 {
|
rlm@1
|
937 *b++ = *pixU8++; // B
|
rlm@1
|
938 *b++ = *pixU8++; // G
|
rlm@1
|
939 *b++ = *pixU8++; // R
|
rlm@1
|
940 }
|
rlm@1
|
941 pixU8 -= 2*3*w;
|
rlm@1
|
942 fwrite(writeBuffer, 1, 3*w, fp);
|
rlm@1
|
943
|
rlm@1
|
944 b = writeBuffer;
|
rlm@1
|
945 }
|
rlm@1
|
946
|
rlm@1
|
947 fclose(fp);
|
rlm@1
|
948 }
|
rlm@1
|
949
|
rlm@1
|
950 void MapView::savePNG(const char *name)
|
rlm@1
|
951 {
|
rlm@1
|
952 u8 writeBuffer[1024 * 3];
|
rlm@1
|
953
|
rlm@1
|
954 FILE *fp = fopen(name, "wb");
|
rlm@1
|
955
|
rlm@1
|
956 if (!fp)
|
rlm@1
|
957 {
|
rlm@1
|
958 systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s", name);
|
rlm@1
|
959 return;
|
rlm@1
|
960 }
|
rlm@1
|
961
|
rlm@1
|
962 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
rlm@1
|
963 NULL,
|
rlm@1
|
964 NULL,
|
rlm@1
|
965 NULL);
|
rlm@1
|
966 if (!png_ptr)
|
rlm@1
|
967 {
|
rlm@1
|
968 fclose(fp);
|
rlm@1
|
969 return;
|
rlm@1
|
970 }
|
rlm@1
|
971
|
rlm@1
|
972 png_infop info_ptr = png_create_info_struct(png_ptr);
|
rlm@1
|
973
|
rlm@1
|
974 if (!info_ptr)
|
rlm@1
|
975 {
|
rlm@1
|
976 png_destroy_write_struct(&png_ptr, NULL);
|
rlm@1
|
977 fclose(fp);
|
rlm@1
|
978 return;
|
rlm@1
|
979 }
|
rlm@1
|
980
|
rlm@1
|
981 if (setjmp(png_ptr->jmpbuf))
|
rlm@1
|
982 {
|
rlm@1
|
983 png_destroy_write_struct(&png_ptr, NULL);
|
rlm@1
|
984 fclose(fp);
|
rlm@1
|
985 return;
|
rlm@1
|
986 }
|
rlm@1
|
987
|
rlm@1
|
988 png_init_io(png_ptr, fp);
|
rlm@1
|
989
|
rlm@1
|
990 png_set_IHDR(png_ptr,
|
rlm@1
|
991 info_ptr,
|
rlm@1
|
992 w,
|
rlm@1
|
993 h,
|
rlm@1
|
994 8,
|
rlm@1
|
995 PNG_COLOR_TYPE_RGB,
|
rlm@1
|
996 PNG_INTERLACE_NONE,
|
rlm@1
|
997 PNG_COMPRESSION_TYPE_DEFAULT,
|
rlm@1
|
998 PNG_FILTER_TYPE_DEFAULT);
|
rlm@1
|
999
|
rlm@1
|
1000 png_write_info(png_ptr, info_ptr);
|
rlm@1
|
1001
|
rlm@1
|
1002 u8 *b = writeBuffer;
|
rlm@1
|
1003
|
rlm@1
|
1004 int sizeX = w;
|
rlm@1
|
1005 int sizeY = h;
|
rlm@1
|
1006
|
rlm@1
|
1007 u8 *pixU8 = (u8 *)data;
|
rlm@1
|
1008 for (int y = 0; y < sizeY; y++)
|
rlm@1
|
1009 {
|
rlm@1
|
1010 for (int x = 0; x < sizeX; x++)
|
rlm@1
|
1011 {
|
rlm@1
|
1012 int blue = *pixU8++;
|
rlm@1
|
1013 int green = *pixU8++;
|
rlm@1
|
1014 int red = *pixU8++;
|
rlm@1
|
1015
|
rlm@1
|
1016 *b++ = red;
|
rlm@1
|
1017 *b++ = green;
|
rlm@1
|
1018 *b++ = blue;
|
rlm@1
|
1019 }
|
rlm@1
|
1020 png_write_row(png_ptr, writeBuffer);
|
rlm@1
|
1021
|
rlm@1
|
1022 b = writeBuffer;
|
rlm@1
|
1023 }
|
rlm@1
|
1024
|
rlm@1
|
1025 png_write_end(png_ptr, info_ptr);
|
rlm@1
|
1026
|
rlm@1
|
1027 png_destroy_write_struct(&png_ptr, &info_ptr);
|
rlm@1
|
1028
|
rlm@1
|
1029 fclose(fp);
|
rlm@1
|
1030 }
|
rlm@1
|
1031
|
rlm@1
|
1032 void MapView::OnSave()
|
rlm@1
|
1033 {
|
rlm@1
|
1034 CString filename;
|
rlm@1
|
1035
|
rlm@1
|
1036 if (theApp.captureFormat == 0)
|
rlm@1
|
1037 filename = "map.png";
|
rlm@1
|
1038 else
|
rlm@1
|
1039 filename = "map.bmp";
|
rlm@1
|
1040
|
rlm@1
|
1041 LPCTSTR exts[] = {".png", ".bmp", NULL };
|
rlm@1
|
1042
|
rlm@1
|
1043 CString filter = winResLoadFilter(IDS_FILTER_PNG);
|
rlm@1
|
1044 CString title = winResLoadString(IDS_SELECT_CAPTURE_NAME);
|
rlm@1
|
1045
|
rlm@1
|
1046 FileDlg dlg(this,
|
rlm@1
|
1047 filename,
|
rlm@1
|
1048 filter,
|
rlm@1
|
1049 theApp.captureFormat ? 2 : 1,
|
rlm@1
|
1050 theApp.captureFormat ? "BMP" : "PNG",
|
rlm@1
|
1051 exts,
|
rlm@1
|
1052 "",
|
rlm@1
|
1053 title,
|
rlm@1
|
1054 true);
|
rlm@1
|
1055
|
rlm@1
|
1056 if (dlg.DoModal() == IDCANCEL)
|
rlm@1
|
1057 {
|
rlm@1
|
1058 return;
|
rlm@1
|
1059 }
|
rlm@1
|
1060
|
rlm@1
|
1061 if (dlg.getFilterIndex() == 2)
|
rlm@1
|
1062 saveBMP(dlg.GetPathName());
|
rlm@1
|
1063 else
|
rlm@1
|
1064 savePNG(dlg.GetPathName());
|
rlm@1
|
1065 }
|
rlm@1
|
1066
|