rlm@1: // GBPrinter.cpp : implementation file rlm@1: // rlm@1: rlm@1: #include "stdafx.h" rlm@1: #include "resource.h" rlm@1: #include "GBPrinterDlg.h" rlm@1: #include "FileDlg.h" rlm@1: #include "Reg.h" rlm@1: #include "WinResUtil.h" rlm@1: #include "VBA.h" rlm@1: rlm@1: //#include "../common/System.h" rlm@1: #include "../NLS.h" rlm@1: #include "../common/Util.h" rlm@1: rlm@1: extern "C" { rlm@1: #include rlm@1: } rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // GBPrinter dialog rlm@1: rlm@1: GBPrinterDlg::GBPrinterDlg(CWnd*pParent /*=NULL*/) rlm@1: : CDialog(GBPrinterDlg::IDD, pParent) rlm@1: { rlm@1: //{{AFX_DATA_INIT(GBPrinterDlg) rlm@1: m_scale = -1; rlm@1: //}}AFX_DATA_INIT rlm@1: bitmap = (BITMAPINFO *)bitmapHeader; rlm@1: rlm@1: bitmap->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); rlm@1: bitmap->bmiHeader.biWidth = 160; rlm@1: bitmap->bmiHeader.biHeight = -144; rlm@1: bitmap->bmiHeader.biPlanes = 1; rlm@1: bitmap->bmiHeader.biBitCount = 8; rlm@1: bitmap->bmiHeader.biCompression = BI_RGB; rlm@1: bitmap->bmiHeader.biSizeImage = 160*144; rlm@1: bitmap->bmiHeader.biXPelsPerMeter = 0; rlm@1: bitmap->bmiHeader.biYPelsPerMeter = 0; rlm@1: bitmap->bmiHeader.biClrUsed = 4; rlm@1: bitmap->bmiHeader.biClrImportant = 4; rlm@1: bitmap->bmiColors[0].rgbBlue = rlm@1: bitmap->bmiColors[0].rgbGreen = rlm@1: bitmap->bmiColors[0].rgbRed = rlm@1: 255; rlm@1: bitmap->bmiColors[0].rgbReserved = 0; rlm@1: bitmap->bmiColors[1].rgbBlue = rlm@1: bitmap->bmiColors[1].rgbGreen = rlm@1: bitmap->bmiColors[1].rgbRed = rlm@1: 168; rlm@1: bitmap->bmiColors[1].rgbReserved = 0; rlm@1: bitmap->bmiColors[2].rgbBlue = rlm@1: bitmap->bmiColors[2].rgbGreen = rlm@1: bitmap->bmiColors[2].rgbRed = rlm@1: 96; rlm@1: bitmap->bmiColors[2].rgbReserved = 0; rlm@1: bitmap->bmiColors[3].rgbBlue = rlm@1: bitmap->bmiColors[3].rgbGreen = rlm@1: bitmap->bmiColors[3].rgbRed = rlm@1: 0; rlm@1: bitmap->bmiColors[3].rgbReserved = 0; rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::DoDataExchange(CDataExchange*pDX) rlm@1: { rlm@1: CDialog::DoDataExchange(pDX); rlm@1: //{{AFX_DATA_MAP(GBPrinterDlg) rlm@1: DDX_Radio(pDX, IDC_1X, m_scale); rlm@1: //}}AFX_DATA_MAP rlm@1: } rlm@1: rlm@1: BEGIN_MESSAGE_MAP(GBPrinterDlg, CDialog) rlm@1: //{{AFX_MSG_MAP(GBPrinterDlg) rlm@1: ON_BN_CLICKED(ID_SAVE, OnSave) rlm@1: ON_BN_CLICKED(ID_PRINT, OnPrint) rlm@1: ON_BN_CLICKED(ID_OK, OnOk) rlm@1: ON_BN_CLICKED(IDC_1X, On1x) rlm@1: ON_BN_CLICKED(IDC_2X, On2x) rlm@1: ON_BN_CLICKED(IDC_3X, On3x) rlm@1: ON_BN_CLICKED(IDC_4X, On4x) rlm@1: ON_WM_PAINT() rlm@1: //}}AFX_MSG_MAP rlm@1: END_MESSAGE_MAP() rlm@1: rlm@1: ///////////////////////////////////////////////////////////////////////////// rlm@1: // GBPrinter message handlers rlm@1: rlm@1: void GBPrinterDlg::saveAsBMP(const char *name) rlm@1: { rlm@1: u8 writeBuffer[512 * 3]; rlm@1: rlm@1: FILE *fp = fopen(name, "wb"); rlm@1: rlm@1: if (!fp) rlm@1: { rlm@1: systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s", name); rlm@1: return; rlm@1: } rlm@1: rlm@1: struct rlm@1: { rlm@1: u8 ident[2]; rlm@1: u8 filesize[4]; rlm@1: u8 reserved[4]; rlm@1: u8 dataoffset[4]; rlm@1: u8 headersize[4]; rlm@1: u8 width[4]; rlm@1: u8 height[4]; rlm@1: u8 planes[2]; rlm@1: u8 bitsperpixel[2]; rlm@1: u8 compression[4]; rlm@1: u8 datasize[4]; rlm@1: u8 hres[4]; rlm@1: u8 vres[4]; rlm@1: u8 colors[4]; rlm@1: u8 importantcolors[4]; rlm@1: u8 pad[2]; rlm@1: } bmpheader; rlm@1: memset(&bmpheader, 0, sizeof(bmpheader)); rlm@1: rlm@1: bmpheader.ident[0] = 'B'; rlm@1: bmpheader.ident[1] = 'M'; rlm@1: rlm@1: u32 fsz = sizeof(bmpheader) + 160*144*3; rlm@1: utilPutDword(bmpheader.filesize, fsz); rlm@1: utilPutDword(bmpheader.dataoffset, 0x38); rlm@1: utilPutDword(bmpheader.headersize, 0x28); rlm@1: utilPutDword(bmpheader.width, 160); rlm@1: utilPutDword(bmpheader.height, 144); rlm@1: utilPutDword(bmpheader.planes, 1); rlm@1: utilPutDword(bmpheader.bitsperpixel, 24); rlm@1: utilPutDword(bmpheader.datasize, 160*144); rlm@1: rlm@1: fwrite(&bmpheader, 1, sizeof(bmpheader), fp); rlm@1: rlm@1: u8 *b = writeBuffer; rlm@1: u8 *data = (u8 *)bitmapData; rlm@1: u8 *p = data + (160*143); rlm@1: for (int y = 0; y < 144; y++) rlm@1: { rlm@1: for (int x = 0; x < 160; x++) rlm@1: { rlm@1: u8 c = *p++; rlm@1: rlm@1: *b++ = bitmap->bmiColors[c].rgbBlue; rlm@1: *b++ = bitmap->bmiColors[c].rgbGreen; rlm@1: *b++ = bitmap->bmiColors[c].rgbRed; rlm@1: } rlm@1: p -= 2*(160); rlm@1: fwrite(writeBuffer, 1, 3*160, fp); rlm@1: rlm@1: b = writeBuffer; rlm@1: } rlm@1: rlm@1: fclose(fp); rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::saveAsPNG(const char *name) rlm@1: { rlm@1: u8 writeBuffer[160 * 3]; rlm@1: rlm@1: FILE *fp = fopen(name, "wb"); rlm@1: rlm@1: if (!fp) rlm@1: { rlm@1: systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s", rlm@1: name); rlm@1: return; rlm@1: } rlm@1: rlm@1: png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, rlm@1: NULL, rlm@1: NULL, rlm@1: NULL); rlm@1: if (!png_ptr) rlm@1: { rlm@1: fclose(fp); rlm@1: return; rlm@1: } rlm@1: rlm@1: png_infop info_ptr = png_create_info_struct(png_ptr); rlm@1: rlm@1: if (!info_ptr) rlm@1: { rlm@1: png_destroy_write_struct(&png_ptr, NULL); rlm@1: fclose(fp); rlm@1: return; rlm@1: } rlm@1: rlm@1: if (setjmp(png_ptr->jmpbuf)) rlm@1: { rlm@1: png_destroy_write_struct(&png_ptr, NULL); rlm@1: fclose(fp); rlm@1: return; rlm@1: } rlm@1: rlm@1: png_init_io(png_ptr, fp); rlm@1: rlm@1: png_set_IHDR(png_ptr, rlm@1: info_ptr, rlm@1: 160, rlm@1: 144, rlm@1: 8, rlm@1: PNG_COLOR_TYPE_RGB, rlm@1: PNG_INTERLACE_NONE, rlm@1: PNG_COMPRESSION_TYPE_DEFAULT, rlm@1: PNG_FILTER_TYPE_DEFAULT); rlm@1: rlm@1: png_write_info(png_ptr, info_ptr); rlm@1: rlm@1: u8 *b = writeBuffer; rlm@1: rlm@1: int sizeX = 160; rlm@1: int sizeY = 144; rlm@1: rlm@1: u8 *pixU8 = (u8 *)bitmapData; rlm@1: for (int y = 0; y < sizeY; y++) rlm@1: { rlm@1: for (int x = 0; x < sizeX; x++) rlm@1: { rlm@1: u8 c = *pixU8++; rlm@1: *b++ = bitmap->bmiColors[c].rgbRed; rlm@1: *b++ = bitmap->bmiColors[c].rgbGreen; rlm@1: *b++ = bitmap->bmiColors[c].rgbBlue; rlm@1: } rlm@1: png_write_row(png_ptr, writeBuffer); rlm@1: rlm@1: b = writeBuffer; rlm@1: } rlm@1: rlm@1: png_write_end(png_ptr, info_ptr); rlm@1: rlm@1: png_destroy_write_struct(&png_ptr, &info_ptr); rlm@1: rlm@1: fclose(fp); rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::OnSave() rlm@1: { rlm@1: CString captureBuffer; rlm@1: rlm@1: if (theApp.captureFormat == 0) rlm@1: captureBuffer = "printer.png"; rlm@1: else rlm@1: captureBuffer = "printer.bmp"; rlm@1: rlm@1: LPCTSTR exts[] = {".png", ".bmp", NULL }; rlm@1: rlm@1: CString filter = winResLoadFilter(IDS_FILTER_PNG); rlm@1: CString title = winResLoadString(IDS_SELECT_CAPTURE_NAME); rlm@1: rlm@1: FileDlg dlg(this, rlm@1: captureBuffer, rlm@1: filter, rlm@1: theApp.captureFormat ? 2 : 1, rlm@1: theApp.captureFormat ? "BMP" : "PNG", rlm@1: exts, rlm@1: "", rlm@1: title, rlm@1: true); rlm@1: rlm@1: if (dlg.DoModal() == IDCANCEL) rlm@1: { rlm@1: return; rlm@1: } rlm@1: rlm@1: captureBuffer = dlg.GetPathName(); rlm@1: rlm@1: if (dlg.getFilterIndex() == 2) rlm@1: saveAsBMP(captureBuffer); rlm@1: else rlm@1: saveAsPNG(captureBuffer); rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::OnPrint() rlm@1: { rlm@1: CPrintDialog dlg(FALSE); rlm@1: rlm@1: dlg.m_pd.nFromPage = 1; rlm@1: dlg.m_pd.nToPage = 1; rlm@1: dlg.m_pd.nMinPage = 1; rlm@1: dlg.m_pd.nMaxPage = 1; rlm@1: dlg.m_pd.nCopies = 1; rlm@1: rlm@1: if (dlg.DoModal() == IDOK) rlm@1: { rlm@1: DOCINFO di; rlm@1: float fLogPelsX1 = 0; rlm@1: float fLogPelsX2 = 0; rlm@1: float fLogPelsY1 = 0; rlm@1: float fLogPelsY2 = 0; rlm@1: float fScaleX = 0, fScaleY = 0; rlm@1: CDC * winDC = NULL; rlm@1: memset(&di, 0, sizeof(di)); rlm@1: di.cbSize = sizeof(DOCINFO); rlm@1: CString docName = winResLoadString(IDS_POCKET_PRINTER); rlm@1: di.lpszDocName = docName; rlm@1: CDC dc; rlm@1: dc.Attach(dlg.GetPrinterDC()); rlm@1: int nError = dc.StartDoc(&di); rlm@1: rlm@1: if (nError == SP_ERROR) rlm@1: { rlm@1: systemMessage(IDS_ERROR_ON_STARTDOC, "Error on StartDoc"); rlm@1: goto error; rlm@1: } rlm@1: nError = dc.StartPage(); rlm@1: if (nError <= 0) rlm@1: { rlm@1: systemMessage(IDS_ERROR_ON_STARTPAGE, "Error on StartPage"); rlm@1: goto error; rlm@1: } rlm@1: rlm@1: winDC = GetDC(); rlm@1: fLogPelsX1 = (float)winDC->GetDeviceCaps(LOGPIXELSX); rlm@1: fLogPelsY1 = (float)winDC->GetDeviceCaps(LOGPIXELSY); rlm@1: ReleaseDC(winDC); rlm@1: rlm@1: fLogPelsX2 = (float)dc.GetDeviceCaps(LOGPIXELSX); rlm@1: fLogPelsY2 = (float)dc.GetDeviceCaps(LOGPIXELSY); rlm@1: rlm@1: if (fLogPelsX1 > fLogPelsX2) rlm@1: fScaleX = fLogPelsX1 / fLogPelsX2; rlm@1: else rlm@1: fScaleX = fLogPelsX2 / fLogPelsX1; rlm@1: rlm@1: if (fLogPelsY1 > fLogPelsY2) rlm@1: fScaleY = fLogPelsY1 / fLogPelsY2; rlm@1: else rlm@1: fScaleY = fLogPelsY2 / fLogPelsY1; rlm@1: rlm@1: fScaleX *= (scale+1); rlm@1: fScaleY *= (scale+1); rlm@1: rlm@1: if (StretchDIBits(dc, rlm@1: 0, rlm@1: 0, rlm@1: (int)((float)160*fScaleX), rlm@1: (int)((float)144*fScaleY), rlm@1: 0, rlm@1: 0, rlm@1: 160, rlm@1: 144, rlm@1: bitmapData, rlm@1: bitmap, rlm@1: DIB_RGB_COLORS, rlm@1: SRCCOPY) == GDI_ERROR) rlm@1: { rlm@1: systemMessage(IDS_ERROR_PRINTING_ON_STRETCH, rlm@1: "Error printing on StretchDIBits"); rlm@1: } rlm@1: rlm@1: nError = dc.EndPage(); rlm@1: rlm@1: if (nError <= 0) rlm@1: { rlm@1: systemMessage(IDS_ERROR_ON_ENDPAGE, "Error on EndPage"); rlm@1: goto error; rlm@1: } rlm@1: rlm@1: nError = dc.EndDoc(); rlm@1: rlm@1: if (nError <= 0) rlm@1: systemMessage(IDS_ERROR_ON_ENDDOC, "Error on EndDoc"); rlm@1: error: rlm@1: dc.DeleteDC(); rlm@1: } rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::processData(u8 *data) rlm@1: { rlm@1: for (int y = 0; y < 0x12; y++) rlm@1: { rlm@1: for (int x = 0; x < 0x14; x++) rlm@1: { rlm@1: for (int k = 0; k < 8; k++) rlm@1: { rlm@1: int a = *data++; rlm@1: int b = *data++; rlm@1: for (int j = 0; j < 8; j++) rlm@1: { rlm@1: int mask = 1 << (7-j); rlm@1: int c = 0; rlm@1: if (a & mask) rlm@1: c++; rlm@1: if (b & mask) rlm@1: c += 2; rlm@1: bitmapData[x*8+j + 160*(y*8+k)] = c; rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: } rlm@1: rlm@1: BOOL GBPrinterDlg::OnInitDialog() rlm@1: { rlm@1: CDialog::OnInitDialog(); rlm@1: rlm@1: scale = regQueryDwordValue("printerScale", 0); rlm@1: if (scale < 0 || scale > 3) rlm@1: scale = 0; rlm@1: m_scale = scale; rlm@1: UpdateData(FALSE); rlm@1: rlm@1: CenterWindow(); rlm@1: rlm@1: return TRUE; // return TRUE unless you set the focus to a control rlm@1: // EXCEPTION: OCX Property Pages should return FALSE rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::OnOk() rlm@1: { rlm@1: EndDialog(TRUE); rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::On1x() rlm@1: { rlm@1: regSetDwordValue("printerScale", 0); rlm@1: scale = 0; rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::On2x() rlm@1: { rlm@1: regSetDwordValue("printerScale", 1); rlm@1: scale = 1; rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::On3x() rlm@1: { rlm@1: regSetDwordValue("printerScale", 2); rlm@1: scale = 2; rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::On4x() rlm@1: { rlm@1: regSetDwordValue("printerScale", 3); rlm@1: scale = 3; rlm@1: } rlm@1: rlm@1: void GBPrinterDlg::OnPaint() rlm@1: { rlm@1: CPaintDC dc(this); // device context for painting rlm@1: rlm@1: RECT rect; rlm@1: CWnd *h = GetDlgItem(IDC_GB_PRINTER); rlm@1: h->GetWindowRect(&rect); rlm@1: POINT p; rlm@1: p.x = rect.left; rlm@1: p.y = rect.top; rlm@1: ScreenToClient((POINT *)&p); rlm@1: rect.left = p.x+1; rlm@1: rect.top = p.y+1; rlm@1: p.x = rect.right; rlm@1: p.y = rect.bottom; rlm@1: ScreenToClient((POINT *)&p); rlm@1: rect.right = p.x-1; rlm@1: rect.bottom = p.y-1; rlm@1: rlm@1: StretchDIBits(dc, rlm@1: rect.left, rlm@1: rect.top, rlm@1: rect.right - rect.left, rlm@1: rect.bottom - rect.top, rlm@1: 0, rlm@1: 0, rlm@1: 160, rlm@1: 144, rlm@1: bitmapData, rlm@1: bitmap, rlm@1: DIB_RGB_COLORS, rlm@1: SRCCOPY); rlm@1: } rlm@1: rlm@1: void systemGbPrint(u8 *data, rlm@1: int pages, rlm@1: int feed, rlm@1: int palette, rlm@1: int contrast) rlm@1: { rlm@1: theApp.winCheckFullscreen(); rlm@1: GBPrinterDlg printer; rlm@1: printer.processData(data); rlm@1: printer.DoModal(); rlm@1: } rlm@1: