home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / win32 / PaletteViewControl.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-13  |  8.5 KB  |  410 lines

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