view src/win32/GBPrinterDlg.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 // GBPrinter.cpp : implementation file
2 //
4 #include "stdafx.h"
5 #include "resource.h"
6 #include "GBPrinterDlg.h"
7 #include "FileDlg.h"
8 #include "Reg.h"
9 #include "WinResUtil.h"
10 #include "VBA.h"
12 //#include "../common/System.h"
13 #include "../NLS.h"
14 #include "../common/Util.h"
16 extern "C" {
17 #include <png.h>
18 }
20 /////////////////////////////////////////////////////////////////////////////
21 // GBPrinter dialog
23 GBPrinterDlg::GBPrinterDlg(CWnd*pParent /*=NULL*/)
24 : CDialog(GBPrinterDlg::IDD, pParent)
25 {
26 //{{AFX_DATA_INIT(GBPrinterDlg)
27 m_scale = -1;
28 //}}AFX_DATA_INIT
29 bitmap = (BITMAPINFO *)bitmapHeader;
31 bitmap->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
32 bitmap->bmiHeader.biWidth = 160;
33 bitmap->bmiHeader.biHeight = -144;
34 bitmap->bmiHeader.biPlanes = 1;
35 bitmap->bmiHeader.biBitCount = 8;
36 bitmap->bmiHeader.biCompression = BI_RGB;
37 bitmap->bmiHeader.biSizeImage = 160*144;
38 bitmap->bmiHeader.biXPelsPerMeter = 0;
39 bitmap->bmiHeader.biYPelsPerMeter = 0;
40 bitmap->bmiHeader.biClrUsed = 4;
41 bitmap->bmiHeader.biClrImportant = 4;
42 bitmap->bmiColors[0].rgbBlue =
43 bitmap->bmiColors[0].rgbGreen =
44 bitmap->bmiColors[0].rgbRed =
45 255;
46 bitmap->bmiColors[0].rgbReserved = 0;
47 bitmap->bmiColors[1].rgbBlue =
48 bitmap->bmiColors[1].rgbGreen =
49 bitmap->bmiColors[1].rgbRed =
50 168;
51 bitmap->bmiColors[1].rgbReserved = 0;
52 bitmap->bmiColors[2].rgbBlue =
53 bitmap->bmiColors[2].rgbGreen =
54 bitmap->bmiColors[2].rgbRed =
55 96;
56 bitmap->bmiColors[2].rgbReserved = 0;
57 bitmap->bmiColors[3].rgbBlue =
58 bitmap->bmiColors[3].rgbGreen =
59 bitmap->bmiColors[3].rgbRed =
60 0;
61 bitmap->bmiColors[3].rgbReserved = 0;
62 }
64 void GBPrinterDlg::DoDataExchange(CDataExchange*pDX)
65 {
66 CDialog::DoDataExchange(pDX);
67 //{{AFX_DATA_MAP(GBPrinterDlg)
68 DDX_Radio(pDX, IDC_1X, m_scale);
69 //}}AFX_DATA_MAP
70 }
72 BEGIN_MESSAGE_MAP(GBPrinterDlg, CDialog)
73 //{{AFX_MSG_MAP(GBPrinterDlg)
74 ON_BN_CLICKED(ID_SAVE, OnSave)
75 ON_BN_CLICKED(ID_PRINT, OnPrint)
76 ON_BN_CLICKED(ID_OK, OnOk)
77 ON_BN_CLICKED(IDC_1X, On1x)
78 ON_BN_CLICKED(IDC_2X, On2x)
79 ON_BN_CLICKED(IDC_3X, On3x)
80 ON_BN_CLICKED(IDC_4X, On4x)
81 ON_WM_PAINT()
82 //}}AFX_MSG_MAP
83 END_MESSAGE_MAP()
85 /////////////////////////////////////////////////////////////////////////////
86 // GBPrinter message handlers
88 void GBPrinterDlg::saveAsBMP(const char *name)
89 {
90 u8 writeBuffer[512 * 3];
92 FILE *fp = fopen(name, "wb");
94 if (!fp)
95 {
96 systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s", name);
97 return;
98 }
100 struct
101 {
102 u8 ident[2];
103 u8 filesize[4];
104 u8 reserved[4];
105 u8 dataoffset[4];
106 u8 headersize[4];
107 u8 width[4];
108 u8 height[4];
109 u8 planes[2];
110 u8 bitsperpixel[2];
111 u8 compression[4];
112 u8 datasize[4];
113 u8 hres[4];
114 u8 vres[4];
115 u8 colors[4];
116 u8 importantcolors[4];
117 u8 pad[2];
118 } bmpheader;
119 memset(&bmpheader, 0, sizeof(bmpheader));
121 bmpheader.ident[0] = 'B';
122 bmpheader.ident[1] = 'M';
124 u32 fsz = sizeof(bmpheader) + 160*144*3;
125 utilPutDword(bmpheader.filesize, fsz);
126 utilPutDword(bmpheader.dataoffset, 0x38);
127 utilPutDword(bmpheader.headersize, 0x28);
128 utilPutDword(bmpheader.width, 160);
129 utilPutDword(bmpheader.height, 144);
130 utilPutDword(bmpheader.planes, 1);
131 utilPutDword(bmpheader.bitsperpixel, 24);
132 utilPutDword(bmpheader.datasize, 160*144);
134 fwrite(&bmpheader, 1, sizeof(bmpheader), fp);
136 u8 *b = writeBuffer;
137 u8 *data = (u8 *)bitmapData;
138 u8 *p = data + (160*143);
139 for (int y = 0; y < 144; y++)
140 {
141 for (int x = 0; x < 160; x++)
142 {
143 u8 c = *p++;
145 *b++ = bitmap->bmiColors[c].rgbBlue;
146 *b++ = bitmap->bmiColors[c].rgbGreen;
147 *b++ = bitmap->bmiColors[c].rgbRed;
148 }
149 p -= 2*(160);
150 fwrite(writeBuffer, 1, 3*160, fp);
152 b = writeBuffer;
153 }
155 fclose(fp);
156 }
158 void GBPrinterDlg::saveAsPNG(const char *name)
159 {
160 u8 writeBuffer[160 * 3];
162 FILE *fp = fopen(name, "wb");
164 if (!fp)
165 {
166 systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s",
167 name);
168 return;
169 }
171 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
172 NULL,
173 NULL,
174 NULL);
175 if (!png_ptr)
176 {
177 fclose(fp);
178 return;
179 }
181 png_infop info_ptr = png_create_info_struct(png_ptr);
183 if (!info_ptr)
184 {
185 png_destroy_write_struct(&png_ptr, NULL);
186 fclose(fp);
187 return;
188 }
190 if (setjmp(png_ptr->jmpbuf))
191 {
192 png_destroy_write_struct(&png_ptr, NULL);
193 fclose(fp);
194 return;
195 }
197 png_init_io(png_ptr, fp);
199 png_set_IHDR(png_ptr,
200 info_ptr,
201 160,
202 144,
203 8,
204 PNG_COLOR_TYPE_RGB,
205 PNG_INTERLACE_NONE,
206 PNG_COMPRESSION_TYPE_DEFAULT,
207 PNG_FILTER_TYPE_DEFAULT);
209 png_write_info(png_ptr, info_ptr);
211 u8 *b = writeBuffer;
213 int sizeX = 160;
214 int sizeY = 144;
216 u8 *pixU8 = (u8 *)bitmapData;
217 for (int y = 0; y < sizeY; y++)
218 {
219 for (int x = 0; x < sizeX; x++)
220 {
221 u8 c = *pixU8++;
222 *b++ = bitmap->bmiColors[c].rgbRed;
223 *b++ = bitmap->bmiColors[c].rgbGreen;
224 *b++ = bitmap->bmiColors[c].rgbBlue;
225 }
226 png_write_row(png_ptr, writeBuffer);
228 b = writeBuffer;
229 }
231 png_write_end(png_ptr, info_ptr);
233 png_destroy_write_struct(&png_ptr, &info_ptr);
235 fclose(fp);
236 }
238 void GBPrinterDlg::OnSave()
239 {
240 CString captureBuffer;
242 if (theApp.captureFormat == 0)
243 captureBuffer = "printer.png";
244 else
245 captureBuffer = "printer.bmp";
247 LPCTSTR exts[] = {".png", ".bmp", NULL };
249 CString filter = winResLoadFilter(IDS_FILTER_PNG);
250 CString title = winResLoadString(IDS_SELECT_CAPTURE_NAME);
252 FileDlg dlg(this,
253 captureBuffer,
254 filter,
255 theApp.captureFormat ? 2 : 1,
256 theApp.captureFormat ? "BMP" : "PNG",
257 exts,
258 "",
259 title,
260 true);
262 if (dlg.DoModal() == IDCANCEL)
263 {
264 return;
265 }
267 captureBuffer = dlg.GetPathName();
269 if (dlg.getFilterIndex() == 2)
270 saveAsBMP(captureBuffer);
271 else
272 saveAsPNG(captureBuffer);
273 }
275 void GBPrinterDlg::OnPrint()
276 {
277 CPrintDialog dlg(FALSE);
279 dlg.m_pd.nFromPage = 1;
280 dlg.m_pd.nToPage = 1;
281 dlg.m_pd.nMinPage = 1;
282 dlg.m_pd.nMaxPage = 1;
283 dlg.m_pd.nCopies = 1;
285 if (dlg.DoModal() == IDOK)
286 {
287 DOCINFO di;
288 float fLogPelsX1 = 0;
289 float fLogPelsX2 = 0;
290 float fLogPelsY1 = 0;
291 float fLogPelsY2 = 0;
292 float fScaleX = 0, fScaleY = 0;
293 CDC * winDC = NULL;
294 memset(&di, 0, sizeof(di));
295 di.cbSize = sizeof(DOCINFO);
296 CString docName = winResLoadString(IDS_POCKET_PRINTER);
297 di.lpszDocName = docName;
298 CDC dc;
299 dc.Attach(dlg.GetPrinterDC());
300 int nError = dc.StartDoc(&di);
302 if (nError == SP_ERROR)
303 {
304 systemMessage(IDS_ERROR_ON_STARTDOC, "Error on StartDoc");
305 goto error;
306 }
307 nError = dc.StartPage();
308 if (nError <= 0)
309 {
310 systemMessage(IDS_ERROR_ON_STARTPAGE, "Error on StartPage");
311 goto error;
312 }
314 winDC = GetDC();
315 fLogPelsX1 = (float)winDC->GetDeviceCaps(LOGPIXELSX);
316 fLogPelsY1 = (float)winDC->GetDeviceCaps(LOGPIXELSY);
317 ReleaseDC(winDC);
319 fLogPelsX2 = (float)dc.GetDeviceCaps(LOGPIXELSX);
320 fLogPelsY2 = (float)dc.GetDeviceCaps(LOGPIXELSY);
322 if (fLogPelsX1 > fLogPelsX2)
323 fScaleX = fLogPelsX1 / fLogPelsX2;
324 else
325 fScaleX = fLogPelsX2 / fLogPelsX1;
327 if (fLogPelsY1 > fLogPelsY2)
328 fScaleY = fLogPelsY1 / fLogPelsY2;
329 else
330 fScaleY = fLogPelsY2 / fLogPelsY1;
332 fScaleX *= (scale+1);
333 fScaleY *= (scale+1);
335 if (StretchDIBits(dc,
336 0,
337 0,
338 (int)((float)160*fScaleX),
339 (int)((float)144*fScaleY),
340 0,
341 0,
342 160,
343 144,
344 bitmapData,
345 bitmap,
346 DIB_RGB_COLORS,
347 SRCCOPY) == GDI_ERROR)
348 {
349 systemMessage(IDS_ERROR_PRINTING_ON_STRETCH,
350 "Error printing on StretchDIBits");
351 }
353 nError = dc.EndPage();
355 if (nError <= 0)
356 {
357 systemMessage(IDS_ERROR_ON_ENDPAGE, "Error on EndPage");
358 goto error;
359 }
361 nError = dc.EndDoc();
363 if (nError <= 0)
364 systemMessage(IDS_ERROR_ON_ENDDOC, "Error on EndDoc");
365 error:
366 dc.DeleteDC();
367 }
368 }
370 void GBPrinterDlg::processData(u8 *data)
371 {
372 for (int y = 0; y < 0x12; y++)
373 {
374 for (int x = 0; x < 0x14; x++)
375 {
376 for (int k = 0; k < 8; k++)
377 {
378 int a = *data++;
379 int b = *data++;
380 for (int j = 0; j < 8; j++)
381 {
382 int mask = 1 << (7-j);
383 int c = 0;
384 if (a & mask)
385 c++;
386 if (b & mask)
387 c += 2;
388 bitmapData[x*8+j + 160*(y*8+k)] = c;
389 }
390 }
391 }
392 }
393 }
395 BOOL GBPrinterDlg::OnInitDialog()
396 {
397 CDialog::OnInitDialog();
399 scale = regQueryDwordValue("printerScale", 0);
400 if (scale < 0 || scale > 3)
401 scale = 0;
402 m_scale = scale;
403 UpdateData(FALSE);
405 CenterWindow();
407 return TRUE; // return TRUE unless you set the focus to a control
408 // EXCEPTION: OCX Property Pages should return FALSE
409 }
411 void GBPrinterDlg::OnOk()
412 {
413 EndDialog(TRUE);
414 }
416 void GBPrinterDlg::On1x()
417 {
418 regSetDwordValue("printerScale", 0);
419 scale = 0;
420 }
422 void GBPrinterDlg::On2x()
423 {
424 regSetDwordValue("printerScale", 1);
425 scale = 1;
426 }
428 void GBPrinterDlg::On3x()
429 {
430 regSetDwordValue("printerScale", 2);
431 scale = 2;
432 }
434 void GBPrinterDlg::On4x()
435 {
436 regSetDwordValue("printerScale", 3);
437 scale = 3;
438 }
440 void GBPrinterDlg::OnPaint()
441 {
442 CPaintDC dc(this); // device context for painting
444 RECT rect;
445 CWnd *h = GetDlgItem(IDC_GB_PRINTER);
446 h->GetWindowRect(&rect);
447 POINT p;
448 p.x = rect.left;
449 p.y = rect.top;
450 ScreenToClient((POINT *)&p);
451 rect.left = p.x+1;
452 rect.top = p.y+1;
453 p.x = rect.right;
454 p.y = rect.bottom;
455 ScreenToClient((POINT *)&p);
456 rect.right = p.x-1;
457 rect.bottom = p.y-1;
459 StretchDIBits(dc,
460 rect.left,
461 rect.top,
462 rect.right - rect.left,
463 rect.bottom - rect.top,
464 0,
465 0,
466 160,
467 144,
468 bitmapData,
469 bitmap,
470 DIB_RGB_COLORS,
471 SRCCOPY);
472 }
474 void systemGbPrint(u8 *data,
475 int pages,
476 int feed,
477 int palette,
478 int contrast)
479 {
480 theApp.winCheckFullscreen();
481 GBPrinterDlg printer;
482 printer.processData(data);
483 printer.DoModal();
484 }