home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / win32 / VideoMode.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-13  |  10.0 KB  |  366 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. // VideoMode.cpp : implementation file
  20. //
  21.  
  22. #include "stdafx.h"
  23. #include "VBA.h"
  24.  
  25. #define DIRECTDRAW_VERSION 0x0700
  26. #include <ddraw.h>
  27.  
  28. #include "VideoMode.h"
  29.  
  30. #include "../System.h"
  31. #include "resource.h"
  32.  
  33.  
  34. #ifdef _DEBUG
  35. #define new DEBUG_NEW
  36. #undef THIS_FILE
  37. static char THIS_FILE[] = __FILE__;
  38. #endif
  39.  
  40. #define MAX_DRIVERS         32                  // 32 drivers maximum
  41.  
  42. //-----------------------------------------------------------------------------
  43. // Local structures
  44. //-----------------------------------------------------------------------------
  45. // Keeps data on the available DDraw drivers
  46. struct
  47. {
  48.   char        szDescription[128];
  49.   char        szName[128];
  50.   GUID        *pGUID;
  51.   GUID        GUIDcopy;
  52.   HMONITOR    hm;
  53. } Drivers[MAX_DRIVERS];
  54.  
  55. //-----------------------------------------------------------------------------
  56. // Local data
  57. //-----------------------------------------------------------------------------
  58. static int                  gDriverCnt = 0;     // Total number of drivers
  59. static GUID                *gpSelectedDriverGUID;
  60.  
  61. //-----------------------------------------------------------------------------
  62. // Name: DDEnumCallbackEx()
  63. // Desc: This call back is used to determine the existing available DDraw
  64. //       devices, so the user can pick which one to run on.
  65. //-----------------------------------------------------------------------------
  66. BOOL WINAPI 
  67. DDEnumCallbackEx(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID pContext, HMONITOR hm)
  68. {
  69.   if (pGUID)
  70.     {
  71.       Drivers[gDriverCnt].GUIDcopy = *pGUID;
  72.       Drivers[gDriverCnt].pGUID = &Drivers[gDriverCnt].GUIDcopy;
  73.     }
  74.   else
  75.     Drivers[gDriverCnt].pGUID = NULL;
  76.   Drivers[gDriverCnt].szDescription[127] = '\0';
  77.   Drivers[gDriverCnt].szName[127] = '\0';
  78.   strncpy(Drivers[gDriverCnt].szDescription,pDescription,127);
  79.   strncpy(Drivers[gDriverCnt].szName,pName,127);
  80.   Drivers[gDriverCnt].hm = hm;
  81.   if (gDriverCnt < MAX_DRIVERS)
  82.     gDriverCnt++;
  83.   else
  84.     return DDENUMRET_CANCEL;
  85.   return DDENUMRET_OK;
  86. }
  87.  
  88.  
  89.  
  90.  
  91. //-----------------------------------------------------------------------------
  92. // Name: DDEnumCallback()
  93. // Desc: This callback is used only with old versions of DDraw.
  94. //-----------------------------------------------------------------------------
  95. BOOL WINAPI 
  96. DDEnumCallback(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID context)
  97. {
  98.   return (DDEnumCallbackEx(pGUID, pDescription, pName, context, NULL));
  99. }
  100.  
  101. static HRESULT WINAPI addVideoMode(LPDDSURFACEDESC2 surf, LPVOID lpContext)
  102. {
  103.   HWND h = (HWND)lpContext;
  104.   char buffer[50];
  105.   
  106.   switch(surf->ddpfPixelFormat.dwRGBBitCount) {
  107.   case 16:
  108.   case 24:
  109.   case 32:
  110.     if(surf->dwWidth >= 640 && surf->dwHeight >= 480) {
  111.       sprintf(buffer, "%4dx%4dx%2d", surf->dwWidth, surf->dwHeight,
  112.               surf->ddpfPixelFormat.dwRGBBitCount);
  113.       int pos = ::SendMessage(h, LB_ADDSTRING, 0, (LPARAM)buffer);
  114.       ::SendMessage(h, LB_SETITEMDATA, pos,
  115.                     (surf->ddpfPixelFormat.dwRGBBitCount << 24) |
  116.                     ((surf->dwWidth & 4095) << 12) |
  117.                     (surf->dwHeight & 4095));
  118.     }
  119.   }
  120.  
  121.   return DDENUMRET_OK;
  122. }
  123.  
  124. int winVideoModeSelect(CWnd *pWnd, GUID **guid)
  125. {
  126.   HINSTANCE h = AfxLoadLibrary("ddraw.dll");
  127.  
  128.   // If ddraw.dll doesn't exist in the search path,
  129.   // then DirectX probably isn't installed, so fail.
  130.   if (!h)
  131.     return -1;
  132.   
  133.   gDriverCnt = 0;
  134.   
  135.   // Note that you must know which version of the
  136.   // function to retrieve (see the following text).
  137.   // For this example, we use the ANSI version.
  138.   LPDIRECTDRAWENUMERATEEX lpDDEnumEx;
  139.   lpDDEnumEx = (LPDIRECTDRAWENUMERATEEX)
  140.     GetProcAddress(h,"DirectDrawEnumerateExA");
  141.  
  142.   // If the function is there, call it to enumerate all display 
  143.   // devices attached to the desktop, and any non-display DirectDraw
  144.   // devices.
  145.   if (lpDDEnumEx)
  146.     lpDDEnumEx(DDEnumCallbackEx, NULL, 
  147.                DDENUM_ATTACHEDSECONDARYDEVICES |
  148.                DDENUM_NONDISPLAYDEVICES 
  149.                );
  150.   else {
  151.     /*
  152.      * We must be running on an old version of DirectDraw.
  153.      * Therefore MultiMon isn't supported. Fall back on
  154.      * DirectDrawEnumerate to enumerate standard devices on a 
  155.      * single-monitor system.
  156.      */
  157.     BOOL (WINAPI *lpDDEnum)(LPDDENUMCALLBACK, LPVOID);
  158.     
  159.     lpDDEnum = (BOOL (WINAPI *)(LPDDENUMCALLBACK, LPVOID))
  160.       GetProcAddress(h, "DirectDrawEnumerateA");
  161.     if(lpDDEnum)
  162.       lpDDEnum(DDEnumCallback,NULL);
  163.     
  164.     /* Note that it could be handy to let the OldCallback function
  165.      * be a wrapper for a DDEnumCallbackEx. 
  166.      * 
  167.      * Such a function would look like:
  168.      *    BOOL FAR PASCAL OldCallback(GUID FAR *lpGUID,
  169.      *                                LPSTR pDesc,
  170.      *                                LPSTR pName,
  171.      *                                LPVOID pContext)
  172.      *    {
  173.      *         return Callback(lpGUID,pDesc,pName,pContext,NULL);
  174.      *    }
  175.      */
  176.   }
  177.  
  178.   int selected = 0;
  179.  
  180.   if(gDriverCnt > 1) {
  181.     VideoDriverSelect d(pWnd);
  182.  
  183.     selected = d.DoModal();
  184.  
  185.     if(selected == -1) {
  186.       // If the library was loaded by calling LoadLibrary(),
  187.       // then you must use FreeLibrary() to let go of it.
  188.       AfxFreeLibrary(h);
  189.       
  190.       return -1;
  191.     }
  192.   }
  193.  
  194.   HRESULT (WINAPI *DDrawCreateEx)(GUID *,LPVOID *,REFIID,IUnknown *);  
  195.   DDrawCreateEx = (HRESULT (WINAPI *)(GUID *,LPVOID *,REFIID,IUnknown *))
  196.     GetProcAddress(h, "DirectDrawCreateEx");
  197.  
  198.   LPDIRECTDRAW7 ddraw = NULL;
  199.   if(DDrawCreateEx) {
  200.     HRESULT hret = DDrawCreateEx(Drivers[selected].pGUID,
  201.                                  (void **)&ddraw,
  202.                                  IID_IDirectDraw7,
  203.                                  NULL);
  204.     if(hret != DD_OK) {
  205.       systemMessage(0, "Error during DirectDrawCreateEx: %08x", hret);
  206.       AfxFreeLibrary(h);
  207.       return -1;
  208.     }
  209.   } else {
  210.     // should not happen....
  211.     systemMessage(0, "Error getting DirectDrawCreateEx");
  212.     AfxFreeLibrary(h);
  213.     return -1;
  214.   }  
  215.   
  216.   VideoMode dlg(ddraw, pWnd);
  217.  
  218.   int res = dlg.DoModal();
  219.  
  220.   if(res != -1) {
  221.     *guid = Drivers[selected].pGUID;
  222.   }
  223.   ddraw->Release();
  224.   ddraw = NULL;
  225.  
  226.   // If the library was loaded by calling LoadLibrary(),
  227.   // then you must use FreeLibrary() to let go of it.
  228.   AfxFreeLibrary(h);
  229.  
  230.   return res;
  231. }
  232.  
  233. /////////////////////////////////////////////////////////////////////////////
  234. // VideoMode dialog
  235.  
  236.  
  237. VideoMode::VideoMode(LPDIRECTDRAW7 pDraw, CWnd* pParent /*=NULL*/)
  238.   : CDialog(VideoMode::IDD, pParent)
  239. {
  240.   //{{AFX_DATA_INIT(VideoMode)
  241.   // NOTE: the ClassWizard will add member initialization here
  242.   //}}AFX_DATA_INIT
  243.   pDirectDraw = pDraw;
  244. }
  245.  
  246.  
  247. void VideoMode::DoDataExchange(CDataExchange* pDX)
  248. {
  249.   CDialog::DoDataExchange(pDX);
  250.   //{{AFX_DATA_MAP(VideoMode)
  251.   DDX_Control(pDX, IDC_MODES, m_modes);
  252.   //}}AFX_DATA_MAP
  253. }
  254.  
  255.  
  256. BEGIN_MESSAGE_MAP(VideoMode, CDialog)
  257.   //{{AFX_MSG_MAP(VideoMode)
  258.   ON_LBN_SELCHANGE(IDC_MODES, OnSelchangeModes)
  259.   ON_BN_CLICKED(ID_CANCEL, OnCancel)
  260.   ON_BN_CLICKED(ID_OK, OnOk)
  261.   //}}AFX_MSG_MAP
  262.   END_MESSAGE_MAP()
  263.  
  264.   /////////////////////////////////////////////////////////////////////////////
  265. // VideoMode message handlers
  266.  
  267. void VideoMode::OnSelchangeModes() 
  268. {
  269.   int item = m_modes.GetCurSel();
  270.  
  271.   GetDlgItem(ID_OK)->EnableWindow(item != -1);
  272. }
  273.  
  274. void VideoMode::OnCancel() 
  275. {
  276.   EndDialog(-1);
  277. }
  278.  
  279. void VideoMode::OnOk() 
  280. {
  281.   int cur = m_modes.GetCurSel();
  282.  
  283.   if(cur != -1) {
  284.     cur = m_modes.GetItemData(cur);
  285.   }
  286.   EndDialog(cur);
  287. }
  288.  
  289. BOOL VideoMode::OnInitDialog() 
  290. {
  291.   CDialog::OnInitDialog();
  292.   
  293.   // check for available fullscreen modes
  294.   pDirectDraw->EnumDisplayModes(DDEDM_STANDARDVGAMODES, NULL, m_modes.m_hWnd,
  295.                                 addVideoMode);
  296.   
  297.   GetDlgItem(ID_OK)->EnableWindow(FALSE);      
  298.   CenterWindow();
  299.  
  300.   return TRUE;  // return TRUE unless you set the focus to a control
  301.                 // EXCEPTION: OCX Property Pages should return FALSE
  302. }
  303.  
  304. /////////////////////////////////////////////////////////////////////////////
  305. // VideoDriverSelect dialog
  306.  
  307.  
  308. VideoDriverSelect::VideoDriverSelect(CWnd* pParent /*=NULL*/)
  309.   : CDialog(VideoDriverSelect::IDD, pParent)
  310. {
  311.   //{{AFX_DATA_INIT(VideoDriverSelect)
  312.   // NOTE: the ClassWizard will add member initialization here
  313.   //}}AFX_DATA_INIT
  314. }
  315.  
  316.  
  317. void VideoDriverSelect::DoDataExchange(CDataExchange* pDX)
  318. {
  319.   CDialog::DoDataExchange(pDX);
  320.   //{{AFX_DATA_MAP(VideoDriverSelect)
  321.   DDX_Control(pDX, IDC_DRIVERS, m_drivers);
  322.   //}}AFX_DATA_MAP
  323. }
  324.  
  325.  
  326. BEGIN_MESSAGE_MAP(VideoDriverSelect, CDialog)
  327.   //{{AFX_MSG_MAP(VideoDriverSelect)
  328.   ON_BN_CLICKED(ID_OK, OnOk)
  329.   ON_BN_CLICKED(ID_CANCEL, OnCancel)
  330.     ON_LBN_SELCHANGE(IDC_DRIVERS, OnSelchangeDrivers)
  331.     //}}AFX_MSG_MAP
  332.   END_MESSAGE_MAP()
  333.  
  334.   /////////////////////////////////////////////////////////////////////////////
  335. // VideoDriverSelect message handlers
  336.  
  337. void VideoDriverSelect::OnCancel() 
  338. {
  339.   EndDialog(-1);
  340. }
  341.  
  342. void VideoDriverSelect::OnOk() 
  343. {
  344.   EndDialog(m_drivers.GetCurSel());
  345. }
  346.  
  347. BOOL VideoDriverSelect::OnInitDialog() 
  348. {
  349.   CDialog::OnInitDialog();
  350.   
  351.   for(int i = 0; i < gDriverCnt; i++) {
  352.     m_drivers.AddString(Drivers[i].szDescription);
  353.   }
  354.   
  355.   GetDlgItem(ID_OK)->EnableWindow(FALSE);      
  356.   CenterWindow();
  357.   
  358.   return TRUE;  // return TRUE unless you set the focus to a control
  359.                 // EXCEPTION: OCX Property Pages should return FALSE
  360. }
  361.  
  362. void VideoDriverSelect::OnSelchangeDrivers() 
  363. {
  364.     GetDlgItem(ID_OK)->EnableWindow(m_drivers.GetCurSel() != -1);
  365. }
  366.