rlm@1
|
1 // PaletteViewControl.cpp : implementation file
|
rlm@1
|
2 //
|
rlm@1
|
3
|
rlm@1
|
4 #include "stdafx.h"
|
rlm@1
|
5 #include "PaletteViewControl.h"
|
rlm@1
|
6
|
rlm@1
|
7 #include "../common/Util.h"
|
rlm@1
|
8
|
rlm@1
|
9 bool PaletteViewControl::isRegistered = false;
|
rlm@1
|
10
|
rlm@1
|
11 /////////////////////////////////////////////////////////////////////////////
|
rlm@1
|
12 // PaletteViewControl
|
rlm@1
|
13
|
rlm@1
|
14 PaletteViewControl::PaletteViewControl()
|
rlm@1
|
15 {
|
rlm@1
|
16 memset(&bmpInfo.bmiHeader, 0, sizeof(bmpInfo.bmiHeader));
|
rlm@1
|
17
|
rlm@1
|
18 bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader);
|
rlm@1
|
19 bmpInfo.bmiHeader.biWidth = 256;
|
rlm@1
|
20 bmpInfo.bmiHeader.biHeight = -256;
|
rlm@1
|
21 bmpInfo.bmiHeader.biPlanes = 1;
|
rlm@1
|
22 bmpInfo.bmiHeader.biBitCount = 24;
|
rlm@1
|
23 bmpInfo.bmiHeader.biCompression = BI_RGB;
|
rlm@1
|
24 data = (u8 *)malloc(3 * 256 * 256);
|
rlm@1
|
25
|
rlm@1
|
26 w = 256;
|
rlm@1
|
27 h = 256;
|
rlm@1
|
28
|
rlm@1
|
29 colors = 256;
|
rlm@1
|
30
|
rlm@1
|
31 paletteAddress = 0;
|
rlm@1
|
32
|
rlm@1
|
33 ZeroMemory(palette, 512);
|
rlm@1
|
34
|
rlm@1
|
35 selected = -1;
|
rlm@1
|
36 registerClass();
|
rlm@1
|
37 }
|
rlm@1
|
38
|
rlm@1
|
39 PaletteViewControl::~PaletteViewControl()
|
rlm@1
|
40 {
|
rlm@1
|
41 if(data)
|
rlm@1
|
42 free(data);
|
rlm@1
|
43 }
|
rlm@1
|
44
|
rlm@1
|
45
|
rlm@1
|
46 BEGIN_MESSAGE_MAP(PaletteViewControl, CWnd)
|
rlm@1
|
47 //{{AFX_MSG_MAP(PaletteViewControl)
|
rlm@1
|
48 ON_WM_LBUTTONDOWN()
|
rlm@1
|
49 ON_WM_ERASEBKGND()
|
rlm@1
|
50 ON_WM_PAINT()
|
rlm@1
|
51 //}}AFX_MSG_MAP
|
rlm@1
|
52 END_MESSAGE_MAP()
|
rlm@1
|
53
|
rlm@1
|
54
|
rlm@1
|
55 /////////////////////////////////////////////////////////////////////////////
|
rlm@1
|
56 // PaletteViewControl message handlers
|
rlm@1
|
57
|
rlm@1
|
58 void PaletteViewControl::init(int c, int w, int h)
|
rlm@1
|
59 {
|
rlm@1
|
60 this->w = w;
|
rlm@1
|
61 this->h = h;
|
rlm@1
|
62 this->colors = c;
|
rlm@1
|
63
|
rlm@1
|
64 bmpInfo.bmiHeader.biWidth = w;
|
rlm@1
|
65 bmpInfo.bmiHeader.biHeight = -h;
|
rlm@1
|
66 }
|
rlm@1
|
67
|
rlm@1
|
68
|
rlm@1
|
69 bool PaletteViewControl::saveAdobe(const char *name)
|
rlm@1
|
70 {
|
rlm@1
|
71 FILE *f = fopen(name, "wb");
|
rlm@1
|
72
|
rlm@1
|
73 if(!f)
|
rlm@1
|
74 return false;
|
rlm@1
|
75
|
rlm@1
|
76 for(int i = 0; i < colors; i++) {
|
rlm@1
|
77 u16 c = palette[i];
|
rlm@1
|
78 int r = (c & 0x1f) << 3;
|
rlm@1
|
79 int g = (c & 0x3e0) >> 2;
|
rlm@1
|
80 int b = (c & 0x7c00) >> 7;
|
rlm@1
|
81
|
rlm@1
|
82 u8 data[3] = { r, g, b };
|
rlm@1
|
83 fwrite(data, 1, 3, f);
|
rlm@1
|
84 }
|
rlm@1
|
85 if(colors < 256) {
|
rlm@1
|
86 for(int i = colors; i < 256; i++) {
|
rlm@1
|
87 u8 data[3] = { 0, 0, 0 };
|
rlm@1
|
88 fwrite(data, 1, 3, f);
|
rlm@1
|
89 }
|
rlm@1
|
90 }
|
rlm@1
|
91 fclose(f);
|
rlm@1
|
92
|
rlm@1
|
93 return true;
|
rlm@1
|
94 }
|
rlm@1
|
95
|
rlm@1
|
96
|
rlm@1
|
97 bool PaletteViewControl::saveMSPAL(const char *name)
|
rlm@1
|
98 {
|
rlm@1
|
99 FILE *f = fopen(name, "wb");
|
rlm@1
|
100
|
rlm@1
|
101 if(!f)
|
rlm@1
|
102 return false;
|
rlm@1
|
103
|
rlm@1
|
104 u8 data[4] = { 'R', 'I', 'F', 'F' };
|
rlm@1
|
105
|
rlm@1
|
106 fwrite(data, 1, 4, f);
|
rlm@1
|
107 utilPutDword(data, 256 * 4 + 16);
|
rlm@1
|
108 fwrite(data, 1, 4, f);
|
rlm@1
|
109 u8 data3[4] = { 'P', 'A', 'L', ' ' };
|
rlm@1
|
110 fwrite(data3, 1, 4, f);
|
rlm@1
|
111 u8 data4[4] = { 'd', 'a', 't', 'a' };
|
rlm@1
|
112 fwrite(data4, 1, 4, f);
|
rlm@1
|
113 utilPutDword(data, 256*4+4);
|
rlm@1
|
114 fwrite(data, 1, 4, f);
|
rlm@1
|
115 utilPutWord(&data[0], 0x0300);
|
rlm@1
|
116 utilPutWord(&data[2], 256); // causes problems if not 16 or 256
|
rlm@1
|
117 fwrite(data, 1, 4, f);
|
rlm@1
|
118
|
rlm@1
|
119 for(int i = 0; i < colors; i++) {
|
rlm@1
|
120 u16 c = palette[i];
|
rlm@1
|
121 int r = (c & 0x1f) << 3;
|
rlm@1
|
122 int g = (c & 0x3e0) >> 2;
|
rlm@1
|
123 int b = (c & 0x7c00) >> 7;
|
rlm@1
|
124
|
rlm@1
|
125 u8 data7[4] = { r, g, b, 0 };
|
rlm@1
|
126 fwrite(data7, 1, 4, f);
|
rlm@1
|
127 }
|
rlm@1
|
128 if(colors < 256) {
|
rlm@1
|
129 for(int i = colors; i < 256; i++) {
|
rlm@1
|
130 u8 data7[4] = { 0, 0, 0, 0 };
|
rlm@1
|
131 fwrite(data7, 1, 4, f);
|
rlm@1
|
132 }
|
rlm@1
|
133 }
|
rlm@1
|
134 fclose(f);
|
rlm@1
|
135
|
rlm@1
|
136 return true;
|
rlm@1
|
137 }
|
rlm@1
|
138
|
rlm@1
|
139
|
rlm@1
|
140 bool PaletteViewControl::saveJASCPAL(const char *name)
|
rlm@1
|
141 {
|
rlm@1
|
142 FILE *f = fopen(name, "wb");
|
rlm@1
|
143
|
rlm@1
|
144 if(!f)
|
rlm@1
|
145 return false;
|
rlm@1
|
146
|
rlm@1
|
147 fprintf(f, "JASC-PAL\r\n0100\r\n256\r\n");
|
rlm@1
|
148
|
rlm@1
|
149 for(int i = 0; i < colors; i++) {
|
rlm@1
|
150 u16 c = palette[i];
|
rlm@1
|
151 int r = (c & 0x1f) << 3;
|
rlm@1
|
152 int g = (c & 0x3e0) >> 2;
|
rlm@1
|
153 int b = (c & 0x7c00) >> 7;
|
rlm@1
|
154
|
rlm@1
|
155 fprintf(f, "%d %d %d\r\n", r, g, b);
|
rlm@1
|
156 }
|
rlm@1
|
157 if(colors < 256) {
|
rlm@1
|
158 for(int i = colors; i < 256; i++)
|
rlm@1
|
159 fprintf(f, "0 0 0\r\n");
|
rlm@1
|
160 }
|
rlm@1
|
161 fclose(f);
|
rlm@1
|
162
|
rlm@1
|
163 return true;
|
rlm@1
|
164 }
|
rlm@1
|
165
|
rlm@1
|
166 void PaletteViewControl::setPaletteAddress(int address)
|
rlm@1
|
167 {
|
rlm@1
|
168 paletteAddress = address;
|
rlm@1
|
169 }
|
rlm@1
|
170
|
rlm@1
|
171
|
rlm@1
|
172 void PaletteViewControl::setSelected(int s)
|
rlm@1
|
173 {
|
rlm@1
|
174 selected = s;
|
rlm@1
|
175 InvalidateRect(NULL, FALSE);
|
rlm@1
|
176 }
|
rlm@1
|
177
|
rlm@1
|
178
|
rlm@1
|
179 void PaletteViewControl::render(u16 color, int x, int y)
|
rlm@1
|
180 {
|
rlm@1
|
181 u8 *start = data + y*16*w*3 + x*16*3;
|
rlm@1
|
182 int skip = w*3-16*3;
|
rlm@1
|
183
|
rlm@1
|
184 int r = (color & 0x1f) << 3;
|
rlm@1
|
185 int g = (color & 0x3e0) >> 2;
|
rlm@1
|
186 int b = (color & 0x7c00) >> 7;
|
rlm@1
|
187
|
rlm@1
|
188 for(int i = 0; i < 16; i++) {
|
rlm@1
|
189 *start++ = b;
|
rlm@1
|
190 *start++ = g;
|
rlm@1
|
191 *start++ = r;
|
rlm@1
|
192
|
rlm@1
|
193 *start++ = b;
|
rlm@1
|
194 *start++ = g;
|
rlm@1
|
195 *start++ = r;
|
rlm@1
|
196
|
rlm@1
|
197 *start++ = b;
|
rlm@1
|
198 *start++ = g;
|
rlm@1
|
199 *start++ = r;
|
rlm@1
|
200
|
rlm@1
|
201 *start++ = b;
|
rlm@1
|
202 *start++ = g;
|
rlm@1
|
203 *start++ = r;
|
rlm@1
|
204
|
rlm@1
|
205 *start++ = b;
|
rlm@1
|
206 *start++ = g;
|
rlm@1
|
207 *start++ = r;
|
rlm@1
|
208
|
rlm@1
|
209 *start++ = b;
|
rlm@1
|
210 *start++ = g;
|
rlm@1
|
211 *start++ = r;
|
rlm@1
|
212
|
rlm@1
|
213 *start++ = b;
|
rlm@1
|
214 *start++ = g;
|
rlm@1
|
215 *start++ = r;
|
rlm@1
|
216
|
rlm@1
|
217 *start++ = b;
|
rlm@1
|
218 *start++ = g;
|
rlm@1
|
219 *start++ = r;
|
rlm@1
|
220
|
rlm@1
|
221 *start++ = b;
|
rlm@1
|
222 *start++ = g;
|
rlm@1
|
223 *start++ = r;
|
rlm@1
|
224
|
rlm@1
|
225 *start++ = b;
|
rlm@1
|
226 *start++ = g;
|
rlm@1
|
227 *start++ = r;
|
rlm@1
|
228
|
rlm@1
|
229 *start++ = b;
|
rlm@1
|
230 *start++ = g;
|
rlm@1
|
231 *start++ = r;
|
rlm@1
|
232
|
rlm@1
|
233 *start++ = b;
|
rlm@1
|
234 *start++ = g;
|
rlm@1
|
235 *start++ = r;
|
rlm@1
|
236
|
rlm@1
|
237 *start++ = b;
|
rlm@1
|
238 *start++ = g;
|
rlm@1
|
239 *start++ = r;
|
rlm@1
|
240
|
rlm@1
|
241 *start++ = b;
|
rlm@1
|
242 *start++ = g;
|
rlm@1
|
243 *start++ = r;
|
rlm@1
|
244
|
rlm@1
|
245 *start++ = b;
|
rlm@1
|
246 *start++ = g;
|
rlm@1
|
247 *start++ = r;
|
rlm@1
|
248
|
rlm@1
|
249 *start++ = b;
|
rlm@1
|
250 *start++ = g;
|
rlm@1
|
251 *start++ = r;
|
rlm@1
|
252
|
rlm@1
|
253 start += skip;
|
rlm@1
|
254 }
|
rlm@1
|
255 }
|
rlm@1
|
256
|
rlm@1
|
257 void PaletteViewControl::refresh()
|
rlm@1
|
258 {
|
rlm@1
|
259 updatePalette();
|
rlm@1
|
260 int sw = w/16;
|
rlm@1
|
261 int sh = h/16;
|
rlm@1
|
262 for(int i = 0; i < colors; i++) {
|
rlm@1
|
263 render(palette[i], i & (sw-1), i/sw);
|
rlm@1
|
264 }
|
rlm@1
|
265 InvalidateRect(NULL, FALSE);
|
rlm@1
|
266 }
|
rlm@1
|
267
|
rlm@1
|
268 void PaletteViewControl::OnLButtonDown(UINT nFlags, CPoint point)
|
rlm@1
|
269 {
|
rlm@1
|
270 int x = point.x;
|
rlm@1
|
271 int y = point.y;
|
rlm@1
|
272 RECT rect;
|
rlm@1
|
273 GetClientRect(&rect);
|
rlm@1
|
274 int h = rect.bottom - rect.top;
|
rlm@1
|
275 int w = rect.right - rect.left;
|
rlm@1
|
276 int sw = (this->w/16);
|
rlm@1
|
277 int sh = (this->h/16);
|
rlm@1
|
278 int mult = w / sw;
|
rlm@1
|
279 int multY = h / sh;
|
rlm@1
|
280
|
rlm@1
|
281 setSelected(x/mult + (y/multY)*sw);
|
rlm@1
|
282
|
rlm@1
|
283 GetParent()->SendMessage(WM_PALINFO,
|
rlm@1
|
284 palette[x/mult+(y/multY)*sw],
|
rlm@1
|
285 paletteAddress+(x/mult+(y/multY)*sw));
|
rlm@1
|
286 }
|
rlm@1
|
287
|
rlm@1
|
288 BOOL PaletteViewControl::OnEraseBkgnd(CDC* pDC)
|
rlm@1
|
289 {
|
rlm@1
|
290 return TRUE;
|
rlm@1
|
291 }
|
rlm@1
|
292
|
rlm@1
|
293
|
rlm@1
|
294 void PaletteViewControl::OnPaint()
|
rlm@1
|
295 {
|
rlm@1
|
296 CPaintDC dc(this); // device context for painting
|
rlm@1
|
297
|
rlm@1
|
298 RECT rect;
|
rlm@1
|
299 GetClientRect(&rect);
|
rlm@1
|
300 int w = rect.right - rect.left;
|
rlm@1
|
301 int h = rect.bottom - rect.top;
|
rlm@1
|
302
|
rlm@1
|
303 CDC memDC;
|
rlm@1
|
304 memDC.CreateCompatibleDC(&dc);
|
rlm@1
|
305 CBitmap bitmap, *pOldBitmap;
|
rlm@1
|
306 bitmap.CreateCompatibleBitmap(&dc, w, h);
|
rlm@1
|
307 pOldBitmap = memDC.SelectObject(&bitmap);
|
rlm@1
|
308
|
rlm@1
|
309 StretchDIBits(memDC.GetSafeHdc(),
|
rlm@1
|
310 0,
|
rlm@1
|
311 0,
|
rlm@1
|
312 w,
|
rlm@1
|
313 h,
|
rlm@1
|
314 0,
|
rlm@1
|
315 0,
|
rlm@1
|
316 this->w,
|
rlm@1
|
317 this->h,
|
rlm@1
|
318 data,
|
rlm@1
|
319 &bmpInfo,
|
rlm@1
|
320 DIB_RGB_COLORS,
|
rlm@1
|
321 SRCCOPY);
|
rlm@1
|
322 int sw = this->w / 16;
|
rlm@1
|
323 int sh = this->h / 16;
|
rlm@1
|
324 int mult = w / sw;
|
rlm@1
|
325 int multY = h / sh;
|
rlm@1
|
326 CPen pen;
|
rlm@1
|
327 pen.CreatePen(PS_SOLID, 1, RGB(192,192,192));
|
rlm@1
|
328 CPen *old = memDC.SelectObject(&pen);
|
rlm@1
|
329 int i;
|
rlm@1
|
330 for(i = 1; i < sh; i++) {
|
rlm@1
|
331 memDC.MoveTo(0, i * multY);
|
rlm@1
|
332 memDC.LineTo(w, i * multY);
|
rlm@1
|
333 }
|
rlm@1
|
334 for(i = 1; i < sw; i++) {
|
rlm@1
|
335 memDC.MoveTo(i * mult, 0);
|
rlm@1
|
336 memDC.LineTo(i * mult, h);
|
rlm@1
|
337 }
|
rlm@1
|
338 memDC.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT);
|
rlm@1
|
339 memDC.SelectObject(old);
|
rlm@1
|
340 pen.DeleteObject();
|
rlm@1
|
341
|
rlm@1
|
342 if(selected != -1) {
|
rlm@1
|
343 pen.CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
|
rlm@1
|
344 old = memDC.SelectObject(&pen);
|
rlm@1
|
345
|
rlm@1
|
346 int startX = (selected & (sw-1))*mult+1;
|
rlm@1
|
347 int startY = (selected / sw)*multY+1;
|
rlm@1
|
348 int endX = startX + mult-2;
|
rlm@1
|
349 int endY = startY + multY-2;
|
rlm@1
|
350
|
rlm@1
|
351 memDC.MoveTo(startX, startY);
|
rlm@1
|
352 memDC.LineTo(endX, startY);
|
rlm@1
|
353 memDC.LineTo(endX, endY);
|
rlm@1
|
354 memDC.LineTo(startX, endY);
|
rlm@1
|
355 memDC.LineTo(startX, startY-1);
|
rlm@1
|
356
|
rlm@1
|
357 memDC.SelectObject(old);
|
rlm@1
|
358 pen.DeleteObject();
|
rlm@1
|
359 }
|
rlm@1
|
360
|
rlm@1
|
361 dc.BitBlt(0,0,w,h,
|
rlm@1
|
362 &memDC,0,0,SRCCOPY);
|
rlm@1
|
363
|
rlm@1
|
364 memDC.SelectObject(pOldBitmap);
|
rlm@1
|
365 bitmap.DeleteObject();
|
rlm@1
|
366 memDC.DeleteDC();
|
rlm@1
|
367 }
|
rlm@1
|
368
|
rlm@1
|
369 void PaletteViewControl::registerClass()
|
rlm@1
|
370 {
|
rlm@1
|
371 if(!isRegistered) {
|
rlm@1
|
372 WNDCLASS wc;
|
rlm@1
|
373 ZeroMemory(&wc, sizeof(wc));
|
rlm@1
|
374 wc.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
|
rlm@1
|
375 wc.lpfnWndProc = (WNDPROC)::DefWindowProc;
|
rlm@1
|
376 wc.hInstance = AfxGetInstanceHandle();
|
rlm@1
|
377 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
rlm@1
|
378 wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
|
rlm@1
|
379 wc.lpszMenuName = NULL;
|
rlm@1
|
380 wc.lpszClassName = "VbaPaletteViewControl";
|
rlm@1
|
381 AfxRegisterClass(&wc);
|
rlm@1
|
382 isRegistered = true;
|
rlm@1
|
383 }
|
rlm@1
|
384 }
|