Mercurial > vba-linux
diff src/win32/MapView.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/win32/MapView.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,1066 @@ 1.4 +// MapView.cpp : implementation file 1.5 +// 1.6 + 1.7 +#include "stdafx.h" 1.8 +#include "resource.h" 1.9 +#include "MapView.h" 1.10 +#include "FileDlg.h" 1.11 +#include "Reg.h" 1.12 +#include "WinResUtil.h" 1.13 +#include "VBA.h" 1.14 + 1.15 +#include "../gba/GBAGlobals.h" 1.16 +#include "../NLS.h" 1.17 +#include "../common/Util.h" 1.18 + 1.19 +extern "C" { 1.20 +#include <png.h> 1.21 +} 1.22 + 1.23 +///////////////////////////////////////////////////////////////////////////// 1.24 +// MapView dialog 1.25 + 1.26 +MapView::MapView(CWnd*pParent /*=NULL*/) 1.27 + : ResizeDlg(MapView::IDD, pParent) 1.28 +{ 1.29 + //{{AFX_DATA_INIT(MapView) 1.30 + //}}AFX_DATA_INIT 1.31 + autoUpdate = false; 1.32 + 1.33 + memset(&bmpInfo.bmiHeader, 0, sizeof(bmpInfo.bmiHeader)); 1.34 + 1.35 + bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader); 1.36 + bmpInfo.bmiHeader.biWidth = 1024; 1.37 + bmpInfo.bmiHeader.biHeight = -1024; 1.38 + bmpInfo.bmiHeader.biPlanes = 1; 1.39 + bmpInfo.bmiHeader.biBitCount = 24; 1.40 + bmpInfo.bmiHeader.biCompression = BI_RGB; 1.41 + data = (u8 *)calloc(1, 3 * 1024 * 1024); 1.42 + 1.43 + mapView.setData(data); 1.44 + mapView.setBmpInfo(&bmpInfo); 1.45 + 1.46 + control = BG0CNT; 1.47 + 1.48 + bg = 0; 1.49 + frame = 0; 1.50 +} 1.51 + 1.52 +MapView::~MapView() 1.53 +{ 1.54 + free(data); 1.55 + data = NULL; 1.56 +} 1.57 + 1.58 +void MapView::DoDataExchange(CDataExchange*pDX) 1.59 +{ 1.60 + CDialog::DoDataExchange(pDX); 1.61 + //{{AFX_DATA_MAP(MapView) 1.62 + DDX_Control(pDX, IDC_NUMCOLORS, m_numcolors); 1.63 + DDX_Control(pDX, IDC_MODE, m_mode); 1.64 + DDX_Control(pDX, IDC_OVERFLOW, m_overflow); 1.65 + DDX_Control(pDX, IDC_MOSAIC, m_mosaic); 1.66 + DDX_Control(pDX, IDC_PRIORITY, m_priority); 1.67 + DDX_Control(pDX, IDC_DIM, m_dim); 1.68 + DDX_Control(pDX, IDC_CHARBASE, m_charbase); 1.69 + DDX_Control(pDX, IDC_MAPBASE, m_mapbase); 1.70 + //}}AFX_DATA_MAP 1.71 + DDX_Control(pDX, IDC_MAP_VIEW, mapView); 1.72 + DDX_Control(pDX, IDC_MAP_VIEW_ZOOM, mapViewZoom); 1.73 + DDX_Control(pDX, IDC_COLOR, color); 1.74 +} 1.75 + 1.76 +BEGIN_MESSAGE_MAP(MapView, CDialog) 1.77 +//{{AFX_MSG_MAP(MapView) 1.78 +ON_BN_CLICKED(IDC_REFRESH, OnRefresh) 1.79 +ON_BN_CLICKED(IDC_FRAME_0, OnFrame0) 1.80 +ON_BN_CLICKED(IDC_FRAME_1, OnFrame1) 1.81 +ON_BN_CLICKED(IDC_BG0, OnBg0) 1.82 +ON_BN_CLICKED(IDC_BG1, OnBg1) 1.83 +ON_BN_CLICKED(IDC_BG2, OnBg2) 1.84 +ON_BN_CLICKED(IDC_BG3, OnBg3) 1.85 +ON_BN_CLICKED(IDC_STRETCH, OnStretch) 1.86 +ON_BN_CLICKED(IDC_AUTO_UPDATE, OnAutoUpdate) 1.87 +ON_BN_CLICKED(IDC_CLOSE, OnClose) 1.88 +ON_BN_CLICKED(IDC_SAVE, OnSave) 1.89 +//}}AFX_MSG_MAP 1.90 +ON_MESSAGE(WM_MAPINFO, OnMapInfo) 1.91 +ON_MESSAGE(WM_COLINFO, OnColInfo) 1.92 +END_MESSAGE_MAP() 1.93 + 1.94 +///////////////////////////////////////////////////////////////////////////// 1.95 +// MapView message handlers 1.96 + 1.97 +void MapView::renderTextScreen(u16 control) 1.98 +{ 1.99 + u16 *palette = (u16 *)paletteRAM; 1.100 + u8 * charBase = &vram[((control >> 2) & 0x03) * 0x4000]; 1.101 + u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800]; 1.102 + u8 * bmp = data; 1.103 + 1.104 + int sizeX = 256; 1.105 + int sizeY = 256; 1.106 + switch ((control >> 14) & 3) 1.107 + { 1.108 + case 0: 1.109 + break; 1.110 + case 1: 1.111 + sizeX = 512; 1.112 + break; 1.113 + case 2: 1.114 + sizeY = 512; 1.115 + break; 1.116 + case 3: 1.117 + sizeX = 512; 1.118 + sizeY = 512; 1.119 + break; 1.120 + } 1.121 + 1.122 + w = sizeX; 1.123 + h = sizeY; 1.124 + 1.125 + if (control & 0x80) 1.126 + { 1.127 + for (int y = 0; y < sizeY; y++) 1.128 + { 1.129 + int yy = y & 255; 1.130 + 1.131 + if (y == 256 && sizeY > 256) 1.132 + { 1.133 + screenBase += 0x400; 1.134 + if (sizeX > 256) 1.135 + screenBase += 0x400; 1.136 + } 1.137 + u16 *screenSource = screenBase + ((yy>>3)*32); 1.138 + 1.139 + for (int x = 0; x < sizeX; x++) 1.140 + { 1.141 + u16 data = *screenSource; 1.142 + 1.143 + int tile = data & 0x3FF; 1.144 + int tileX = (x & 7); 1.145 + int tileY = y & 7; 1.146 + 1.147 + if (data & 0x0400) 1.148 + tileX = 7 - tileX; 1.149 + if (data & 0x0800) 1.150 + tileY = 7 - tileY; 1.151 + 1.152 + u8 c = charBase[tile * 64 + tileY * 8 + tileX]; 1.153 + 1.154 + u16 color = palette[c]; 1.155 + 1.156 + *bmp++ = ((color >> 10) & 0x1f) << 3; 1.157 + *bmp++ = ((color >> 5) & 0x1f) << 3; 1.158 + *bmp++ = (color & 0x1f) << 3; 1.159 + 1.160 + if (data & 0x0400) 1.161 + { 1.162 + if (tileX == 0) 1.163 + screenSource++; 1.164 + } 1.165 + else if (tileX == 7) 1.166 + screenSource++; 1.167 + if (x == 255 && sizeX > 256) 1.168 + { 1.169 + screenSource = screenBase + 0x400 + ((yy>>3)*32); 1.170 + } 1.171 + } 1.172 + } 1.173 + } 1.174 + else 1.175 + { 1.176 + for (int y = 0; y < sizeY; y++) 1.177 + { 1.178 + int yy = y & 255; 1.179 + 1.180 + if (y == 256 && sizeY > 256) 1.181 + { 1.182 + screenBase += 0x400; 1.183 + if (sizeX > 256) 1.184 + screenBase += 0x400; 1.185 + } 1.186 + u16 *screenSource = screenBase + ((yy>>3)*32); 1.187 + 1.188 + for (int x = 0; x < sizeX; x++) 1.189 + { 1.190 + u16 data = *screenSource; 1.191 + 1.192 + int tile = data & 0x3FF; 1.193 + int tileX = (x & 7); 1.194 + int tileY = y & 7; 1.195 + 1.196 + if (data & 0x0400) 1.197 + tileX = 7 - tileX; 1.198 + if (data & 0x0800) 1.199 + tileY = 7 - tileY; 1.200 + 1.201 + u8 color = charBase[tile * 32 + tileY * 4 + (tileX>>1)]; 1.202 + 1.203 + if (tileX & 1) 1.204 + { 1.205 + color = (color >> 4); 1.206 + } 1.207 + else 1.208 + { 1.209 + color &= 0x0F; 1.210 + } 1.211 + 1.212 + int pal = (*screenSource>>8) & 0xF0; 1.213 + u16 color2 = palette[pal + color]; 1.214 + 1.215 + *bmp++ = ((color2 >> 10) & 0x1f) << 3; 1.216 + *bmp++ = ((color2 >> 5) & 0x1f) << 3; 1.217 + *bmp++ = (color2 & 0x1f) << 3; 1.218 + 1.219 + if (data & 0x0400) 1.220 + { 1.221 + if (tileX == 0) 1.222 + screenSource++; 1.223 + } 1.224 + else if (tileX == 7) 1.225 + screenSource++; 1.226 + 1.227 + if (x == 255 && sizeX > 256) 1.228 + { 1.229 + screenSource = screenBase + 0x400 + ((yy>>3)*32); 1.230 + } 1.231 + } 1.232 + } 1.233 + } 1.234 + /* 1.235 + switch(bg) { 1.236 + case 0: 1.237 + renderView(BG0HOFS<<8, BG0VOFS<<8, 1.238 + 0x100, 0x000, 1.239 + 0x000, 0x100, 1.240 + (sizeX -1) <<8, 1.241 + (sizeY -1) << 8, 1.242 + true); 1.243 + break; 1.244 + case 1: 1.245 + renderView(BG1HOFS<<8, BG1VOFS<<8, 1.246 + 0x100, 0x000, 1.247 + 0x000, 0x100, 1.248 + (sizeX -1) <<8, 1.249 + (sizeY -1) << 8, 1.250 + true); 1.251 + break; 1.252 + case 2: 1.253 + renderView(BG2HOFS<<8, BG2VOFS<<8, 1.254 + 0x100, 0x000, 1.255 + 0x000, 0x100, 1.256 + (sizeX -1) <<8, 1.257 + (sizeY -1) << 8, 1.258 + true); 1.259 + break; 1.260 + case 3: 1.261 + renderView(BG3HOFS<<8, BG3VOFS<<8, 1.262 + 0x100, 0x000, 1.263 + 0x000, 0x100, 1.264 + (sizeX -1) <<8, 1.265 + (sizeY -1) << 8, 1.266 + true); 1.267 + break; 1.268 + } 1.269 + */ 1.270 +} 1.271 + 1.272 +void MapView::renderRotScreen(u16 control) 1.273 +{ 1.274 + u16 *palette = (u16 *)paletteRAM; 1.275 + u8 * charBase = &vram[((control >> 2) & 0x03) * 0x4000]; 1.276 + u8 * screenBase = (u8 *)&vram[((control >> 8) & 0x1f) * 0x800]; 1.277 + u8 * bmp = data; 1.278 + 1.279 + int sizeX = 128; 1.280 + int sizeY = 128; 1.281 + switch ((control >> 14) & 3) 1.282 + { 1.283 + case 0: 1.284 + break; 1.285 + case 1: 1.286 + sizeX = sizeY = 256; 1.287 + break; 1.288 + case 2: 1.289 + sizeX = sizeY = 512; 1.290 + break; 1.291 + case 3: 1.292 + sizeX = sizeY = 1024; 1.293 + break; 1.294 + } 1.295 + 1.296 + w = sizeX; 1.297 + h = sizeY; 1.298 + 1.299 + if (control & 0x80) 1.300 + { 1.301 + for (int y = 0; y < sizeY; y++) 1.302 + { 1.303 + for (int x = 0; x < sizeX; x++) 1.304 + { 1.305 + int tile = screenBase[(x>>3) + (y>>3)*(w>>3)]; 1.306 + 1.307 + int tileX = (x & 7); 1.308 + int tileY = y & 7; 1.309 + 1.310 + u8 color = charBase[tile * 64 + tileY * 8 + tileX]; 1.311 + u16 color2 = palette[color]; 1.312 + 1.313 + *bmp++ = ((color2 >> 10) & 0x1f) << 3; 1.314 + *bmp++ = ((color2 >> 5) & 0x1f) << 3; 1.315 + *bmp++ = (color2 & 0x1f) << 3; 1.316 + } 1.317 + } 1.318 + } 1.319 + else 1.320 + { 1.321 + for (int y = 0; y < sizeY; y++) 1.322 + { 1.323 + for (int x = 0; x < sizeX; x++) 1.324 + { 1.325 + int tile = screenBase[(x>>3) + (y>>3)*(w>>3)]; 1.326 + 1.327 + int tileX = (x & 7); 1.328 + int tileY = y & 7; 1.329 + 1.330 + u8 color = charBase[tile * 64 + tileY * 8 + tileX]; 1.331 + u16 color2 = palette[color]; 1.332 + 1.333 + *bmp++ = ((color2 >> 10) & 0x1f) << 3; 1.334 + *bmp++ = ((color2 >> 5) & 0x1f) << 3; 1.335 + *bmp++ = (color2 & 0x1f) << 3; 1.336 + } 1.337 + } 1.338 + } 1.339 + 1.340 + u32 xx; 1.341 + u32 yy; 1.342 + 1.343 + switch (bg) 1.344 + { 1.345 + case 2: 1.346 + xx = BG2X_L | BG2X_H << 16; 1.347 + yy = BG2Y_L | BG2Y_H << 16; 1.348 + 1.349 + /* 1.350 + renderView(xx, yy, 1.351 + BG2PA, BG2PC, 1.352 + BG2PB, BG2PD, 1.353 + (sizeX -1) <<8, 1.354 + (sizeY -1) << 8, 1.355 + (control & 0x2000) != 0); 1.356 + */ 1.357 + break; 1.358 + case 3: 1.359 + xx = BG3X_L | BG3X_H << 16; 1.360 + yy = BG3Y_L | BG3Y_H << 16; 1.361 + /* 1.362 + renderView(xx, yy, 1.363 + BG3PA, BG3PC, 1.364 + BG3PB, BG3PD, 1.365 + (sizeX -1) <<8, 1.366 + (sizeY -1) << 8, 1.367 + (control & 0x2000) != 0); 1.368 + */ 1.369 + break; 1.370 + } 1.371 +} 1.372 + 1.373 +void MapView::renderMode0() 1.374 +{ 1.375 + renderTextScreen(control); 1.376 +} 1.377 + 1.378 +void MapView::renderMode1() 1.379 +{ 1.380 + switch (bg) 1.381 + { 1.382 + case 0: 1.383 + case 1: 1.384 + renderTextScreen(control); 1.385 + break; 1.386 + case 2: 1.387 + renderRotScreen(control); 1.388 + break; 1.389 + default: 1.390 + bg = 0; 1.391 + control = BG0CNT; 1.392 + renderTextScreen(control); 1.393 + break; 1.394 + } 1.395 +} 1.396 + 1.397 +void MapView::renderMode2() 1.398 +{ 1.399 + switch (bg) 1.400 + { 1.401 + case 2: 1.402 + case 3: 1.403 + renderRotScreen(control); 1.404 + break; 1.405 + default: 1.406 + bg = 2; 1.407 + control = BG2CNT; 1.408 + renderRotScreen(control); 1.409 + break; 1.410 + } 1.411 +} 1.412 + 1.413 +void MapView::renderMode3() 1.414 +{ 1.415 + u8 * bmp = data; 1.416 + u16 *src = (u16 *)&vram[0]; 1.417 + 1.418 + w = 240; 1.419 + h = 160; 1.420 + 1.421 + for (int y = 0; y < 160; y++) 1.422 + { 1.423 + for (int x = 0; x < 240; x++) 1.424 + { 1.425 + u16 data = *src++; 1.426 + *bmp++ = ((data >> 10) & 0x1f) << 3; 1.427 + *bmp++ = ((data >> 5) & 0x1f) << 3; 1.428 + *bmp++ = (data & 0x1f) << 3; 1.429 + } 1.430 + } 1.431 + bg = 2; 1.432 +} 1.433 + 1.434 +void MapView::renderMode4() 1.435 +{ 1.436 + u8 * bmp = data; 1.437 + u8 * src = frame ? &vram[0xa000] : &vram[0]; 1.438 + u16 *pal = (u16 *)&paletteRAM[0]; 1.439 + 1.440 + w = 240; 1.441 + h = 160; 1.442 + 1.443 + for (int y = 0; y < 160; y++) 1.444 + { 1.445 + for (int x = 0; x < 240; x++) 1.446 + { 1.447 + u8 c = *src++; 1.448 + u16 data = pal[c]; 1.449 + *bmp++ = ((data >> 10) & 0x1f) << 3; 1.450 + *bmp++ = ((data >> 5) & 0x1f) << 3; 1.451 + *bmp++ = (data & 0x1f) << 3; 1.452 + } 1.453 + } 1.454 + bg = 2; 1.455 +} 1.456 + 1.457 +void MapView::renderMode5() 1.458 +{ 1.459 + u8 * bmp = data; 1.460 + u16 *src = (u16 *)(frame ? &vram[0xa000] : &vram[0]); 1.461 + 1.462 + w = 160; 1.463 + h = 128; 1.464 + 1.465 + for (int y = 0; y < 128; y++) 1.466 + { 1.467 + for (int x = 0; x < 160; x++) 1.468 + { 1.469 + u16 data = *src++; 1.470 + *bmp++ = ((data >> 10) & 0x1f) << 3; 1.471 + *bmp++ = ((data >> 5) & 0x1f) << 3; 1.472 + *bmp++ = (data & 0x1f) << 3; 1.473 + } 1.474 + } 1.475 + bg = 2; 1.476 +} 1.477 + 1.478 +void MapView::OnRefresh() 1.479 +{ 1.480 + paint(); 1.481 +} 1.482 + 1.483 +void MapView::paint() 1.484 +{ 1.485 + if (vram == NULL) 1.486 + return; 1.487 + int mode = DISPCNT & 7; 1.488 + 1.489 + switch (bg) 1.490 + { 1.491 + default: 1.492 + case 0: 1.493 + control = BG0CNT; 1.494 + break; 1.495 + case 1: 1.496 + control = BG1CNT; 1.497 + break; 1.498 + case 2: 1.499 + control = BG2CNT; 1.500 + break; 1.501 + case 3: 1.502 + control = BG3CNT; 1.503 + break; 1.504 + } 1.505 + 1.506 + switch (mode) 1.507 + { 1.508 + case 0: 1.509 + renderMode0(); 1.510 + break; 1.511 + case 1: 1.512 + renderMode1(); 1.513 + break; 1.514 + case 2: 1.515 + renderMode2(); 1.516 + break; 1.517 + case 3: 1.518 + renderMode3(); 1.519 + break; 1.520 + case 4: 1.521 + renderMode4(); 1.522 + break; 1.523 + case 5: 1.524 + renderMode5(); 1.525 + break; 1.526 + } 1.527 + enableButtons(mode); 1.528 + SIZE s; 1.529 + 1.530 + if (mapView.getStretch()) 1.531 + { 1.532 + mapView.setSize(w, h); 1.533 + s.cx = s.cy = 1; 1.534 + mapView.SetScrollSizes(MM_TEXT, s); 1.535 + } 1.536 + else 1.537 + { 1.538 + mapView.setSize(w, h); 1.539 + s.cx = w; 1.540 + s.cy = h; 1.541 + mapView.SetScrollSizes(MM_TEXT, s); 1.542 + } 1.543 + 1.544 + mapView.refresh(); 1.545 + 1.546 + CString buffer; 1.547 + 1.548 + u32 charBase = ((control >> 2) & 0x03) * 0x4000 + 0x6000000; 1.549 + u32 screenBase = ((control >> 8) & 0x1f) * 0x800 + 0x6000000; 1.550 + 1.551 + buffer.Format("%d", mode); 1.552 + m_mode.SetWindowText(buffer); 1.553 + 1.554 + if (mode >= 3) 1.555 + { 1.556 + m_mapbase.SetWindowText(""); 1.557 + m_charbase.SetWindowText(""); 1.558 + } 1.559 + else 1.560 + { 1.561 + buffer.Format("0x%08X", screenBase); 1.562 + m_mapbase.SetWindowText(buffer); 1.563 + 1.564 + buffer.Format("0x%08X", charBase); 1.565 + m_charbase.SetWindowText(buffer); 1.566 + } 1.567 + 1.568 + buffer.Format("%dx%d", w, h); 1.569 + m_dim.SetWindowText(buffer); 1.570 + 1.571 + m_numcolors.SetWindowText(control & 0x80 ? "256" : "16"); 1.572 + 1.573 + buffer.Format("%d", control & 3); 1.574 + m_priority.SetWindowText(buffer); 1.575 + 1.576 + m_mosaic.SetWindowText(control & 0x40 ? "1" : "0"); 1.577 + 1.578 + m_overflow.SetWindowText(bg <= 1 ? "" : 1.579 + control & 0x2000 ? "1" : "0"); 1.580 +} 1.581 + 1.582 +BOOL MapView::OnInitDialog() 1.583 +{ 1.584 + CDialog::OnInitDialog(); 1.585 + 1.586 + DIALOG_SIZER_START(sz) 1.587 + DIALOG_SIZER_ENTRY(IDC_MAP_VIEW, DS_SizeX | DS_SizeY) 1.588 + DIALOG_SIZER_ENTRY(IDC_REFRESH, DS_MoveY) 1.589 + DIALOG_SIZER_ENTRY(IDC_CLOSE, DS_MoveY) 1.590 + DIALOG_SIZER_ENTRY(IDC_SAVE, DS_MoveY) 1.591 + DIALOG_SIZER_ENTRY(IDC_COLOR, DS_MoveY) 1.592 + DIALOG_SIZER_ENTRY(IDC_R, DS_MoveY) 1.593 + DIALOG_SIZER_ENTRY(IDC_G, DS_MoveY) 1.594 + DIALOG_SIZER_ENTRY(IDC_B, DS_MoveY) 1.595 + DIALOG_SIZER_END() 1.596 + SetData(sz, 1.597 + TRUE, 1.598 + HKEY_CURRENT_USER, 1.599 + "Software\\Emulators\\VisualBoyAdvance\\Viewer\\MapView", 1.600 + NULL); 1.601 + 1.602 + SIZE size; 1.603 + size.cx = 1; 1.604 + size.cy = 1; 1.605 + mapView.SetScrollSizes(MM_TEXT, size); 1.606 + int s = regQueryDwordValue("mapViewStretch", 0); 1.607 + if (s) 1.608 + mapView.setStretch(true); 1.609 + ((CButton *)GetDlgItem(IDC_STRETCH))->SetCheck(s); 1.610 + paint(); 1.611 + 1.612 + return TRUE; // return TRUE unless you set the focus to a control 1.613 + // EXCEPTION: OCX Property Pages should return FALSE 1.614 +} 1.615 + 1.616 +void MapView::PostNcDestroy() 1.617 +{ 1.618 + delete this; 1.619 +} 1.620 + 1.621 +void MapView::enableButtons(int mode) 1.622 +{ 1.623 + bool enable[6] = { true, true, true, true, true, true }; 1.624 + 1.625 + switch (mode) 1.626 + { 1.627 + case 0: 1.628 + enable[4] = false; 1.629 + enable[5] = false; 1.630 + break; 1.631 + case 1: 1.632 + enable[3] = false; 1.633 + enable[4] = false; 1.634 + enable[5] = false; 1.635 + break; 1.636 + case 2: 1.637 + enable[0] = false; 1.638 + enable[1] = false; 1.639 + enable[4] = false; 1.640 + enable[5] = false; 1.641 + break; 1.642 + case 3: 1.643 + enable[0] = false; 1.644 + enable[1] = false; 1.645 + enable[2] = false; 1.646 + enable[3] = false; 1.647 + enable[4] = false; 1.648 + enable[5] = false; 1.649 + break; 1.650 + case 4: 1.651 + enable[0] = false; 1.652 + enable[1] = false; 1.653 + enable[2] = false; 1.654 + enable[3] = false; 1.655 + break; 1.656 + case 5: 1.657 + enable[0] = false; 1.658 + enable[1] = false; 1.659 + enable[2] = false; 1.660 + enable[3] = false; 1.661 + break; 1.662 + } 1.663 + GetDlgItem(IDC_BG0)->EnableWindow(enable[0]); 1.664 + GetDlgItem(IDC_BG1)->EnableWindow(enable[1]); 1.665 + GetDlgItem(IDC_BG2)->EnableWindow(enable[2]); 1.666 + GetDlgItem(IDC_BG3)->EnableWindow(enable[3]); 1.667 + GetDlgItem(IDC_FRAME_0)->EnableWindow(enable[4]); 1.668 + GetDlgItem(IDC_FRAME_1)->EnableWindow(enable[5]); 1.669 + int id = IDC_BG0; 1.670 + switch (bg) 1.671 + { 1.672 + case 1: 1.673 + id = IDC_BG1; 1.674 + break; 1.675 + case 2: 1.676 + id = IDC_BG2; 1.677 + break; 1.678 + case 3: 1.679 + id = IDC_BG3; 1.680 + break; 1.681 + } 1.682 + CheckRadioButton(IDC_BG0, IDC_BG3, id); 1.683 + id = IDC_FRAME_0; 1.684 + if (frame != 0) 1.685 + id = IDC_FRAME_1; 1.686 + CheckRadioButton(IDC_FRAME_0, IDC_FRAME_1, id); 1.687 +} 1.688 + 1.689 +void MapView::OnFrame0() 1.690 +{ 1.691 + frame = 0; 1.692 + paint(); 1.693 +} 1.694 + 1.695 +void MapView::OnFrame1() 1.696 +{ 1.697 + frame = 1; 1.698 + paint(); 1.699 +} 1.700 + 1.701 +void MapView::OnBg0() 1.702 +{ 1.703 + bg = 0; 1.704 + control = BG0CNT; 1.705 + paint(); 1.706 +} 1.707 + 1.708 +void MapView::OnBg1() 1.709 +{ 1.710 + bg = 1; 1.711 + control = BG1CNT; 1.712 + paint(); 1.713 +} 1.714 + 1.715 +void MapView::OnBg2() 1.716 +{ 1.717 + bg = 2; 1.718 + control = BG2CNT; 1.719 + paint(); 1.720 +} 1.721 + 1.722 +void MapView::OnBg3() 1.723 +{ 1.724 + bg = 3; 1.725 + control = BG3CNT; 1.726 + paint(); 1.727 +} 1.728 + 1.729 +void MapView::OnStretch() 1.730 +{ 1.731 + mapView.setStretch(!mapView.getStretch()); 1.732 + paint(); 1.733 + regSetDwordValue("mapViewStretch", mapView.getStretch()); 1.734 +} 1.735 + 1.736 +void MapView::OnAutoUpdate() 1.737 +{ 1.738 + autoUpdate = !autoUpdate; 1.739 + if (autoUpdate) 1.740 + { 1.741 + theApp.winAddUpdateListener(this); 1.742 + } 1.743 + else 1.744 + { 1.745 + theApp.winRemoveUpdateListener(this); 1.746 + } 1.747 +} 1.748 + 1.749 +void MapView::update() 1.750 +{ 1.751 + paint(); 1.752 +} 1.753 + 1.754 +void MapView::OnClose() 1.755 +{ 1.756 + theApp.winRemoveUpdateListener(this); 1.757 + 1.758 + DestroyWindow(); 1.759 +} 1.760 + 1.761 +u32 MapView::GetTextClickAddress(u32 base, int x, int y) 1.762 +{ 1.763 + if (y > 255 && h > 256) 1.764 + { 1.765 + base += 0x800; 1.766 + if (w > 256) 1.767 + base += 0x800; 1.768 + } 1.769 + if (x >= 256) 1.770 + base += 0x800; 1.771 + x &= 255; 1.772 + y &= 255; 1.773 + base += (x>>3)*2 + 64*(y>>3); 1.774 + 1.775 + return base; 1.776 +} 1.777 + 1.778 +u32 MapView::GetClickAddress(int x, int y) 1.779 +{ 1.780 + int mode = DISPCNT & 7; 1.781 + 1.782 + u32 base = ((control >> 8) & 0x1f) * 0x800 + 0x6000000; 1.783 + 1.784 + // all text bgs (16 bits) 1.785 + if (mode == 0 || (mode < 3 && bg < 2)) 1.786 + { 1.787 + return GetTextClickAddress(base, x, y); 1.788 + } 1.789 + // rot bgs (8 bits) 1.790 + if (mode < 3) 1.791 + { 1.792 + return base + (x>>3) + (w>>3)*(y>>3); 1.793 + } 1.794 + // mode 3/5 (16 bits) 1.795 + if (mode != 4) 1.796 + { 1.797 + return 0x6000000 + 0xa000*frame + 2*x + w*y*2; 1.798 + } 1.799 + // mode 4 (8 bits) 1.800 + return 0x6000000 + 0xa000*frame + x + w*y; 1.801 +} 1.802 + 1.803 +LRESULT MapView::OnMapInfo(WPARAM wParam, LPARAM lParam) 1.804 +{ 1.805 + u8 *colors = (u8 *)lParam; 1.806 + mapViewZoom.setColors(colors); 1.807 + 1.808 + int x = wParam & 0xffff; 1.809 + int y = (wParam >> 16); 1.810 + 1.811 + CString buffer; 1.812 + buffer.Format("(%d,%d)", x, y); 1.813 + GetDlgItem(IDC_XY)->SetWindowText(buffer); 1.814 + 1.815 + u32 address = GetClickAddress(x, y); 1.816 + buffer.Format("0x%08X", address); 1.817 + GetDlgItem(IDC_ADDRESS)->SetWindowText(buffer); 1.818 + 1.819 + int mode = DISPCNT & 7; 1.820 + if (mode >= 3) 1.821 + { 1.822 + // bitmap modes 1.823 + GetDlgItem(IDC_TILE_NUM)->SetWindowText("---"); 1.824 + GetDlgItem(IDC_FLIP)->SetWindowText("--"); 1.825 + GetDlgItem(IDC_PALETTE_NUM)->SetWindowText("---"); 1.826 + } 1.827 + else if (mode == 0 || bg < 2) 1.828 + { 1.829 + // text bgs 1.830 + u16 value = *((u16 *)&vram[address - 0x6000000]); 1.831 + 1.832 + int tile = value & 1023; 1.833 + buffer.Format("%d", tile); 1.834 + GetDlgItem(IDC_TILE_NUM)->SetWindowText(buffer); 1.835 + buffer.Empty(); 1.836 + buffer += value & 1024 ? 'H' : '-'; 1.837 + buffer += value & 2048 ? 'V' : '-'; 1.838 + GetDlgItem(IDC_FLIP)->SetWindowText(buffer); 1.839 + 1.840 + if (!(control & 0x80)) 1.841 + { 1.842 + buffer.Format("%d", (value >> 12) & 15); 1.843 + } 1.844 + else 1.845 + buffer = "---"; 1.846 + GetDlgItem(IDC_PALETTE_NUM)->SetWindowText(buffer); 1.847 + } 1.848 + else 1.849 + { 1.850 + // rot bgs 1.851 + GetDlgItem(IDC_TILE_NUM)->SetWindowText("---"); 1.852 + GetDlgItem(IDC_FLIP)->SetWindowText("--"); 1.853 + GetDlgItem(IDC_PALETTE_NUM)->SetWindowText("---"); 1.854 + } 1.855 + 1.856 + return TRUE; 1.857 +} 1.858 + 1.859 +LRESULT MapView::OnColInfo(WPARAM wParam, LPARAM lParam) 1.860 +{ 1.861 + u16 c = (u16)wParam; 1.862 + 1.863 + color.setColor(c); 1.864 + 1.865 + int r = (c & 0x1f); 1.866 + int g = (c & 0x3e0) >> 5; 1.867 + int b = (c & 0x7c00) >> 10; 1.868 + 1.869 + CString buffer; 1.870 + buffer.Format("R: %d", r); 1.871 + GetDlgItem(IDC_R)->SetWindowText(buffer); 1.872 + 1.873 + buffer.Format("G: %d", g); 1.874 + GetDlgItem(IDC_G)->SetWindowText(buffer); 1.875 + 1.876 + buffer.Format("B: %d", b); 1.877 + GetDlgItem(IDC_B)->SetWindowText(buffer); 1.878 + 1.879 + return TRUE; 1.880 +} 1.881 + 1.882 +void MapView::saveBMP(const char *name) 1.883 +{ 1.884 + u8 writeBuffer[1024 * 3]; 1.885 + 1.886 + FILE *fp = fopen(name, "wb"); 1.887 + 1.888 + if (!fp) 1.889 + { 1.890 + systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s", name); 1.891 + return; 1.892 + } 1.893 + 1.894 + struct 1.895 + { 1.896 + u8 ident[2]; 1.897 + u8 filesize[4]; 1.898 + u8 reserved[4]; 1.899 + u8 dataoffset[4]; 1.900 + u8 headersize[4]; 1.901 + u8 width[4]; 1.902 + u8 height[4]; 1.903 + u8 planes[2]; 1.904 + u8 bitsperpixel[2]; 1.905 + u8 compression[4]; 1.906 + u8 datasize[4]; 1.907 + u8 hres[4]; 1.908 + u8 vres[4]; 1.909 + u8 colors[4]; 1.910 + u8 importantcolors[4]; 1.911 + u8 pad[2]; 1.912 + } bmpheader; 1.913 + memset(&bmpheader, 0, sizeof(bmpheader)); 1.914 + 1.915 + bmpheader.ident[0] = 'B'; 1.916 + bmpheader.ident[1] = 'M'; 1.917 + 1.918 + u32 fsz = sizeof(bmpheader) + w*h*3; 1.919 + utilPutDword(bmpheader.filesize, fsz); 1.920 + utilPutDword(bmpheader.dataoffset, 0x38); 1.921 + utilPutDword(bmpheader.headersize, 0x28); 1.922 + utilPutDword(bmpheader.width, w); 1.923 + utilPutDword(bmpheader.height, h); 1.924 + utilPutDword(bmpheader.planes, 1); 1.925 + utilPutDword(bmpheader.bitsperpixel, 24); 1.926 + utilPutDword(bmpheader.datasize, 3*w*h); 1.927 + 1.928 + fwrite(&bmpheader, 1, sizeof(bmpheader), fp); 1.929 + 1.930 + u8 *b = writeBuffer; 1.931 + 1.932 + int sizeX = w; 1.933 + int sizeY = h; 1.934 + 1.935 + u8 *pixU8 = (u8 *)data+3*w*(h-1); 1.936 + for (int y = 0; y < sizeY; y++) 1.937 + { 1.938 + for (int x = 0; x < sizeX; x++) 1.939 + { 1.940 + *b++ = *pixU8++; // B 1.941 + *b++ = *pixU8++; // G 1.942 + *b++ = *pixU8++; // R 1.943 + } 1.944 + pixU8 -= 2*3*w; 1.945 + fwrite(writeBuffer, 1, 3*w, fp); 1.946 + 1.947 + b = writeBuffer; 1.948 + } 1.949 + 1.950 + fclose(fp); 1.951 +} 1.952 + 1.953 +void MapView::savePNG(const char *name) 1.954 +{ 1.955 + u8 writeBuffer[1024 * 3]; 1.956 + 1.957 + FILE *fp = fopen(name, "wb"); 1.958 + 1.959 + if (!fp) 1.960 + { 1.961 + systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s", name); 1.962 + return; 1.963 + } 1.964 + 1.965 + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 1.966 + NULL, 1.967 + NULL, 1.968 + NULL); 1.969 + if (!png_ptr) 1.970 + { 1.971 + fclose(fp); 1.972 + return; 1.973 + } 1.974 + 1.975 + png_infop info_ptr = png_create_info_struct(png_ptr); 1.976 + 1.977 + if (!info_ptr) 1.978 + { 1.979 + png_destroy_write_struct(&png_ptr, NULL); 1.980 + fclose(fp); 1.981 + return; 1.982 + } 1.983 + 1.984 + if (setjmp(png_ptr->jmpbuf)) 1.985 + { 1.986 + png_destroy_write_struct(&png_ptr, NULL); 1.987 + fclose(fp); 1.988 + return; 1.989 + } 1.990 + 1.991 + png_init_io(png_ptr, fp); 1.992 + 1.993 + png_set_IHDR(png_ptr, 1.994 + info_ptr, 1.995 + w, 1.996 + h, 1.997 + 8, 1.998 + PNG_COLOR_TYPE_RGB, 1.999 + PNG_INTERLACE_NONE, 1.1000 + PNG_COMPRESSION_TYPE_DEFAULT, 1.1001 + PNG_FILTER_TYPE_DEFAULT); 1.1002 + 1.1003 + png_write_info(png_ptr, info_ptr); 1.1004 + 1.1005 + u8 *b = writeBuffer; 1.1006 + 1.1007 + int sizeX = w; 1.1008 + int sizeY = h; 1.1009 + 1.1010 + u8 *pixU8 = (u8 *)data; 1.1011 + for (int y = 0; y < sizeY; y++) 1.1012 + { 1.1013 + for (int x = 0; x < sizeX; x++) 1.1014 + { 1.1015 + int blue = *pixU8++; 1.1016 + int green = *pixU8++; 1.1017 + int red = *pixU8++; 1.1018 + 1.1019 + *b++ = red; 1.1020 + *b++ = green; 1.1021 + *b++ = blue; 1.1022 + } 1.1023 + png_write_row(png_ptr, writeBuffer); 1.1024 + 1.1025 + b = writeBuffer; 1.1026 + } 1.1027 + 1.1028 + png_write_end(png_ptr, info_ptr); 1.1029 + 1.1030 + png_destroy_write_struct(&png_ptr, &info_ptr); 1.1031 + 1.1032 + fclose(fp); 1.1033 +} 1.1034 + 1.1035 +void MapView::OnSave() 1.1036 +{ 1.1037 + CString filename; 1.1038 + 1.1039 + if (theApp.captureFormat == 0) 1.1040 + filename = "map.png"; 1.1041 + else 1.1042 + filename = "map.bmp"; 1.1043 + 1.1044 + LPCTSTR exts[] = {".png", ".bmp", NULL }; 1.1045 + 1.1046 + CString filter = winResLoadFilter(IDS_FILTER_PNG); 1.1047 + CString title = winResLoadString(IDS_SELECT_CAPTURE_NAME); 1.1048 + 1.1049 + FileDlg dlg(this, 1.1050 + filename, 1.1051 + filter, 1.1052 + theApp.captureFormat ? 2 : 1, 1.1053 + theApp.captureFormat ? "BMP" : "PNG", 1.1054 + exts, 1.1055 + "", 1.1056 + title, 1.1057 + true); 1.1058 + 1.1059 + if (dlg.DoModal() == IDCANCEL) 1.1060 + { 1.1061 + return; 1.1062 + } 1.1063 + 1.1064 + if (dlg.getFilterIndex() == 2) 1.1065 + saveBMP(dlg.GetPathName()); 1.1066 + else 1.1067 + savePNG(dlg.GetPathName()); 1.1068 +} 1.1069 +