home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser 2002 January / STC_CD_01_2002.iso / JAGUAR / JAG_SRC / SOURCE / JAGULATO.C < prev    next >
C/C++ Source or Header  |  2001-08-18  |  20KB  |  461 lines

  1. ////////////////////////////////////////////////////////////////////////////////
  2. // Jagulator: Atari Jaguar Console Emulation Project (jagulator.c)
  3. // -----------------------------------------------------------------------------
  4. // Jagulator is the Copyright (c) RealityMan 1998-2001 and is provided "as is" 
  5. // without any expressed or implied warranty. I have no Trademarks, Legal or 
  6. // otherwise. Atari, Jaguar and the Atari Logo are copyright Hasbro Inc. All 
  7. // other Copyrights and Trademarks are acknowledged. This project is in no way 
  8. // linked to Atari/Hasbro or other associated Atari companies.                
  9. //
  10. // 07-07-2001 GH: New Source, Rewritten for Release 1.5.0
  11. // 00-00-0000 GH: All Previous Source Considered as Development Code Only
  12.  
  13. #include "core.h"
  14.  
  15. ////////////////////////////////////////////////////////////////////////////////
  16. // Globals
  17.  
  18.    HANDLE  hInst;                      // Global Application Instance
  19.    HWND    hwndMain;                   // Handle to the Main App Window
  20.    HWND    hwndStatus;                 // Handle to Status Bar
  21.    HANDLE  mainthread;                 // Main Thread Handle
  22.    LPDWORD mainthreadid;               // Main Thread ID
  23.    char comd[MAX_PATH];                // Command String
  24.    char sbbuf[MAX_PATH];               // Status Bar String Buffer
  25.  
  26. ////////////////////////////////////////////////////////////////////////////////
  27. // Preferences Dialog
  28.  
  29.    BOOL CALLBACK BinaryLoadDialog( HWND hdwnd, UINT message,
  30.                                    WPARAM wParam, LPARAM lParam )
  31.    {
  32.       static HWND hwndCtrl;            // Dialog Control Window Handle
  33.       static char buf[MAX_PATH];       // Temporary Buffer
  34.  
  35.       switch( message )
  36.       {
  37.          case WM_COMMAND:
  38.             switch( LOWORD( wParam ) )
  39.             {
  40.                case IDOK:              // Close Window - Save Changes
  41.                   strcpy( comd, "rla " );
  42.                   GetDlgItemText( hdwnd, IDC_ADDR, buf, MAX_PATH );
  43.                   strcat( comd, buf );
  44.                   strcat( comd, " " );
  45.                   GetDlgItemText( hdwnd, IDC_FILE, buf, MAX_PATH );
  46.                   strcat( comd, buf );
  47.                   strcat( comd, "\0" );
  48.                   EndDialog( hdwnd, 0 );
  49.                   return( TRUE );
  50.                case IDCANCEL:          // Close Window - Do Not Save Changes
  51.                   EndDialog( hdwnd, 0 );
  52.                   return( TRUE );
  53.             }
  54.             break;
  55.          case WM_INITDIALOG:
  56.             ShowWindow( hdwnd, SW_SHOW );
  57.             hwndCtrl = GetDlgItem( hdwnd, IDC_FILE );
  58.             SetFocus( hwndCtrl );
  59.             break;
  60.       }
  61.       return( FALSE );
  62.    }
  63.  
  64. ////////////////////////////////////////////////////////////////////////////////
  65. // Preferences Dialog
  66.  
  67.    BOOL CALLBACK PreferencesDialog( HWND hdwnd, UINT message,
  68.                                     WPARAM wParam, LPARAM lParam )
  69.    {
  70.       static HWND hwndCtrl;            // Dialog Control Window Handle
  71.       static char cfgpath[MAX_PATH];   // Config File Path
  72.  
  73.       switch( message )
  74.       {
  75.          case WM_COMMAND:
  76.             switch( LOWORD( wParam ) )
  77.             {
  78.                case IDOK:              // Close Window - Save Changes
  79.                   strcpy( cfgpath, cfg.rootpath );    
  80.                   strcat( cfgpath, "jagulator.ini" );  
  81.                   GetDlgItemText( hdwnd, IDC_BOOTPATH, cfg.bootpath,  MAX_PATH);
  82.                   WritePrivateProfileString( "default", "bootpath", 
  83.                                              cfg.bootpath, cfgpath );
  84.                   GetDlgItemText( hdwnd, IDC_ROMPATH, cfg.rompath, MAX_PATH );
  85.                   WritePrivateProfileString( "default", "rompath", 
  86.                                              cfg.rompath, cfgpath );
  87.                   EndDialog( hdwnd, 0 );
  88.                   return( TRUE );
  89.                case IDCANCEL:          // Close Window - Do Not Save Changes
  90.                   EndDialog( hdwnd, 0 );
  91.                   return( TRUE );
  92.             }
  93.             break;
  94.          case WM_INITDIALOG:
  95.             SetDlgItemText( hdwnd, IDC_BOOTPATH, cfg.bootpath );
  96.             SetDlgItemText( hdwnd, IDC_ROMPATH,  cfg.rompath );
  97.             ShowWindow( hdwnd, SW_SHOW );
  98.             hwndCtrl = GetDlgItem( hdwnd, IDCANCEL );
  99.             SetFocus( hwndCtrl );
  100.             break;
  101.       }
  102.       return( FALSE );
  103.    }
  104.  
  105. ////////////////////////////////////////////////////////////////////////////////
  106. // Video Configuration Dialog
  107.  
  108.    BOOL CALLBACK VideoConfigDialog( HWND hdwnd, UINT message,
  109.                                     WPARAM wParam, LPARAM lParam )
  110.    {
  111.       static HWND hwndCtrl;            // Dialog Control Window Handle
  112.       FILE *glinfo;                    // GL Information File
  113.       fpos_t pos;                      // File Position Indicator
  114.       int i, j;                        // Iterator
  115.       char fsd[30];                    // Frame Skip Description
  116.       static char buf[256];            // Temporary Buffer
  117.       static char cfgpath[MAX_PATH];   // Config File Path
  118.       char vm[5][12] = { "512 x 384", "640 x 480", 
  119.                          "800 x 600", "1024 x 768", "1280 x 1024" };
  120.       switch( message )
  121.       {
  122.          case WM_COMMAND:
  123.             switch( LOWORD( wParam ) )
  124.             {
  125.                case IDOK:              // Close Window - Save Changes
  126.                   strcpy( cfgpath, cfg.rootpath );    
  127.                   strcat( cfgpath, "jagulator.ini" );  
  128.  
  129.                   cfg.graphics = SendDlgItemMessage( hdwnd, IDC_GFXENABLE,
  130.                                                      BM_GETCHECK, 0, 0 );
  131.                   itoa( cfg.graphics, buf, 10 );
  132.                   WritePrivateProfileString( "video", "graphics", 
  133.                                              buf, cfgpath );
  134.                   cfg.fullscreen = SendDlgItemMessage( hdwnd, IDC_GLFULL,
  135.                                                        BM_GETCHECK, 0, 0 );
  136.                   itoa( cfg.fullscreen, buf, 10 );
  137.                   WritePrivateProfileString( "video", "fullscreen", 
  138.                                              buf, cfgpath );
  139.                   i = SendDlgItemMessage( hdwnd, IDC_CD16, BM_GETCHECK, 0, 0 );
  140.                   //cfg.cdepth = i ? 16 : 32;
  141.                   //WritePrivateProfileString( "video", "cdepth", 
  142.                   //                           i ? "16" : "32", cfgpath );
  143.                   i = SendDlgItemMessage( hdwnd, IDC_VMODE, CB_GETCURSEL, 0, 0);
  144.                   switch( i )
  145.                   {
  146.                      case 0: strcpy( buf, "512\0"  ); cfg.vres  = 512;
  147.                              strcpy( fsd, "384\0"  ); cfg.hres = 384;
  148.                              break;
  149.                      case 1: strcpy( buf, "640\0"  ); cfg.vres  = 640;
  150.                              strcpy( fsd, "480\0"  ); cfg.hres = 480;
  151.                              break;
  152.                      case 2: strcpy( buf, "800\0"  ); cfg.vres  = 800;
  153.                              strcpy( fsd, "600\0"  ); cfg.hres = 600;
  154.                              break;
  155.                      case 3: strcpy( buf, "1024\0" ); cfg.vres  = 1024;
  156.                              strcpy( fsd, "768\0"  ); cfg.hres = 768;
  157.                              break;
  158.                      case 4: strcpy( buf, "1280\0" ); cfg.vres  = 1280;
  159.                              strcpy( fsd, "1024\0" ); cfg.hres = 1024;
  160.                              break;
  161.                   }
  162.                   WritePrivateProfileString( "video", "hres", buf, cfgpath );
  163.                   WritePrivateProfileString( "video", "vres", fsd, cfgpath );
  164.                   cfg.frameskip = SendDlgItemMessage( hdwnd, IDC_FSKIP, 
  165.                                                       CB_GETCURSEL, 0, 0 );
  166.                   itoa( cfg.frameskip, buf, 10 );
  167.                   WritePrivateProfileString( "video", "frameskip", buf,cfgpath);
  168.                   EndDialog( hdwnd, 0 );
  169.                   return( TRUE );
  170.                case IDCANCEL:          // Close Window - Do Not Save Changes
  171.                   EndDialog( hdwnd, 0 );
  172.                   return( TRUE );
  173.             }
  174.             break;
  175.          case WM_INITDIALOG:
  176.             if( cfg.graphics )
  177.                SendDlgItemMessage( hdwnd, IDC_GFXENABLE, 
  178.                                    BM_SETCHECK, BST_CHECKED, 0 );
  179.             else
  180.                SendDlgItemMessage( hdwnd, IDC_GFXENABLE, 
  181.                                    BM_SETCHECK, BST_UNCHECKED, 0 );
  182.             if( cfg.fullscreen )
  183.                SendDlgItemMessage(hdwnd,IDC_GLFULL,BM_SETCHECK,BST_CHECKED,0);
  184.             else
  185.                SendDlgItemMessage(hdwnd,IDC_GLFULL,BM_SETCHECK,BST_UNCHECKED,0);
  186.  
  187.             //if( cfg.cdepth == 32 )
  188.             //   SendDlgItemMessage(hdwnd,IDC_CD32,BM_SETCHECK,BST_CHECKED,0);
  189.             //else
  190.             //   SendDlgItemMessage(hdwnd,IDC_CD16,BM_SETCHECK,BST_CHECKED,0);
  191.  
  192.             switch( cfg.vres )
  193.             {
  194.                case 1280: j = 4; break;
  195.                case 1024: j = 3; break;
  196.                case 800:  j = 2; break;
  197.                case 640:  j = 1; break;
  198.                case 512: 
  199.                default:   j = 0; break;
  200.             }
  201.             
  202.             for( i = 0; i < 5; i++ )
  203.                SendDlgItemMessage(hdwnd,IDC_VMODE,CB_ADDSTRING,0,(LPARAM)vm[i]);
  204.             SendDlgItemMessage( hdwnd, IDC_VMODE, CB_SETCURSEL, j, 0 );
  205.  
  206.             SendDlgItemMessage( hdwnd, IDC_FSKIP, CB_ADDSTRING, 0,
  207.                                 (LPARAM)"Display Every Frame");
  208.             for( i = 1; i < 10; i++)
  209.             {
  210.                wsprintf( fsd, "Skip %i of every 10 frames", i );
  211.                SendDlgItemMessage(hdwnd,IDC_FSKIP,CB_ADDSTRING,0,(LPARAM)fsd);
  212.             }
  213.             SendDlgItemMessage( hdwnd, IDC_FSKIP,
  214.                                 CB_SETCURSEL, cfg.frameskip, 0 );
  215.  
  216.             GetTempPath( MAX_PATH, buf );
  217.             strcat( buf, "oglinfo" );
  218.             glinfo = fopen( buf, "r" );
  219.  
  220.             pos = 0;
  221.             fgets( cfgpath, MAX_PATH, glinfo );
  222.             SetDlgItemText( hdwnd, IDC_GLVENDOR,    cfgpath );
  223.  
  224.             pos += strlen(cfgpath) + 1;
  225.             fsetpos( glinfo, &pos );
  226.             fgets( cfgpath, MAX_PATH, glinfo );
  227.             SetDlgItemText( hdwnd, IDC_GLRENDERER,  cfgpath );
  228.  
  229.             pos += strlen(cfgpath) + 1;
  230.             fsetpos( glinfo, &pos );
  231.             fgets( cfgpath, MAX_PATH, glinfo );
  232.             SetDlgItemText( hdwnd, IDC_GLVERSION,   cfgpath );
  233.  
  234.             pos += strlen(cfgpath) + 1;
  235.             fsetpos( glinfo, &pos );
  236.             fgets( cfgpath, MAX_PATH, glinfo );
  237.             SetDlgItemText( hdwnd, IDC_GLEXTENSION, cfgpath );
  238.             fclose( glinfo );
  239.  
  240.             ShowWindow( hdwnd, SW_SHOW );
  241.             hwndCtrl = GetDlgItem( hdwnd, IDCANCEL );
  242.             SetFocus( hwndCtrl );
  243.             break;
  244.       }
  245.       return( FALSE );
  246.    }
  247.  
  248. ////////////////////////////////////////////////////////////////////////////////
  249. // About Jagulator Dialog
  250.  
  251.    BOOL CALLBACK AboutDialog( HWND hdwnd, UINT message,
  252.                               WPARAM wParam, LPARAM lParam )
  253.    {
  254.       static HWND hwndCtrl;            // Dialog Control Window Handle
  255.  
  256.       switch( message )
  257.       {
  258.          case WM_COMMAND:
  259.             switch( LOWORD( wParam ) )
  260.             {
  261.                case IDOK:              // Close the Dialog Window
  262.                   EndDialog( hdwnd, 0 );
  263.                   return( TRUE );
  264.             }
  265.             break;
  266.          case WM_INITDIALOG: 
  267.             ShowWindow( hdwnd, SW_SHOW ); 
  268.             hwndCtrl = GetDlgItem( hdwnd, IDOK );
  269.             SetFocus( hwndCtrl );
  270.             break;
  271.       }
  272.       return( FALSE );
  273.    }
  274.  
  275. ////////////////////////////////////////////////////////////////////////////////
  276. // Application Window Message Processing
  277.  
  278.    LRESULT CALLBACK WindowFunc( HWND hwnd,      // Handle to Application Window
  279.                                 UINT message,   // Windows Message
  280.                                 WPARAM wParam,  // Message Parameter
  281.                                 LPARAM lParam ) // Message Parameter
  282.    {
  283.       RECT rcl;                        // Window Size
  284.       HDWP hdwp;                       // Deferred Window Position 
  285.       static char buf[256];            // Temporary Buffer
  286.       static char hlppath[MAX_PATH];   // Config File Path
  287.       const LPSTR HelpFile = "jagulator.hlp";
  288.  
  289.       switch( message )
  290.       {
  291.          case WM_CREATE:               // Do Application Initialisation
  292.             hwndMain = hwnd;           // Set Main Window Handle
  293.  
  294.             hwndStatus = CreateWindowEx( 0L, STATUSCLASSNAME, "", WS_CHILD | 
  295.                                          WS_BORDER | WS_VISIBLE | SBS_SIZEGRIP,
  296.                                          0, 0, 0, 0, hwndMain,
  297.                                          (HMENU)ID_STATUSBAR, hInst, NULL );
  298.             wsprintf( sbbuf, "%s", COPYRIGHT );
  299.             v_getglinfo();             // Get OpenGL Information
  300.             break;
  301.  
  302.          case WM_COMMAND:              // Handle App Defined Windows Messages
  303.             switch( LOWORD( wParam ) )
  304.             {
  305.                case ID_ROM:            // Load Jaguar Binary
  306.                   boot_load();
  307.                   break;
  308.  
  309.                case ID_START:          // Begin Emulation
  310.                   wsprintf( sbbuf, "Emulating..." );
  311.                   SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
  312.                   command( "go" );
  313.                   break;
  314.  
  315.                case ID_RESET:          // Stop and Reset Emulator
  316.                   v_deinit();
  317.                   memset( &st,  0, sizeof( STATE    ) );
  318.                   memset( &gst, 0, sizeof( GPUSTATE ) );
  319.                   memset( &dst, 0, sizeof( DSPSTATE ) );
  320.                   memset( &blt, 0, sizeof( BLTSTATE ) );
  321.                   wsprintf( sbbuf, "%s", COPYRIGHT );
  322.                   SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
  323.                   break;
  324.  
  325.                case ID_EXIT:           // Exit Emulator Requested
  326.                   SendMessage( hwndMain, WM_DESTROY, 0, 0L );
  327.                   break;
  328.  
  329.                case ID_VIDEO:          // Video Configuration
  330.                   DialogBox( hInst, MAKEINTRESOURCE( IDD_VIDEO ),
  331.                              hwndMain, VideoConfigDialog );
  332.                   break;
  333.  
  334.                case ID_PREFS:          // Preferences
  335.                   DialogBox( hInst, MAKEINTRESOURCE( IDD_PREFS ),
  336.                              hwndMain, PreferencesDialog );
  337.                   break;
  338.  
  339.                case ID_TOPICS:         // Jagulator Help File
  340.                   wsprintf( hlppath, "%s%s", cfg.rootpath, HelpFile );
  341.                   WinHelp( hwndMain, hlppath, HELP_INDEX, 0 );
  342.                   break;
  343.  
  344.                case ID_ABOUT:          // Display About Application Details
  345.                   DialogBox( hInst, MAKEINTRESOURCE( IDD_ABOUT ),
  346.                              hwndMain, AboutDialog );
  347.                   break;
  348.  
  349.                default:                // Ignore any other App Defined Messages
  350.                   break;
  351.             }
  352.             break;
  353.  
  354.          case WM_DESTROY:              // Terminate the Application
  355.             PostQuitMessage( 0 );
  356.             break;
  357.  
  358.          case WM_SIZE:                 // Handle Window Resizing
  359.             GetClientRect( hwndMain, &rcl );
  360.  
  361.             hdwp = BeginDeferWindowPos( 1 );
  362.             // Resize Status Bar
  363.             DeferWindowPos( hdwp, hwndStatus, NULL, 0, 0,
  364.                              rcl.right - rcl.left, 20,
  365.                             SWP_NOZORDER | SWP_NOMOVE );
  366.             EndDeferWindowPos( hdwp );
  367.  
  368.             // Refresh Status Bar Elements
  369.             SendMessage( hwndStatus, SB_SETTEXT, 0, (LPARAM)sbbuf );
  370.             break;
  371.  
  372.          default:                      // Handle any Unhandle Windows Messages
  373.             return( DefWindowProc( hwnd, message, wParam, lParam ) );
  374.             break;
  375.       }
  376.  
  377.       return( 0L );                    // Return from Main Win Msg Handling Proc
  378.    }
  379.  
  380. ////////////////////////////////////////////////////////////////////////////////
  381. // Emulator Thread - Basically Calls main.c which returns if the Debug
  382. // User Interface is ever Exited.
  383.  
  384.    int EmuThread( int value )
  385.    {
  386.        main_thread();
  387.        SendMessage( hwndMain, WM_CLOSE, 0, 0 );
  388.        return( 0 );
  389.    }
  390.  
  391. ////////////////////////////////////////////////////////////////////////////////
  392. // Main Application Code Starts Here
  393.  
  394.    int WINAPI WinMain( HINSTANCE hThisInst,  // Handle to this Program Instance
  395.                        HINSTANCE hPrevInst,  // Previous Instance (Obsolete)
  396.                        LPSTR lpszArgs,       // Passed Arguments
  397.                        int nWinMode )        // Windows Display Mode
  398.  
  399.    {
  400.       WNDCLASSEX  wclex;               // Pointer to Windows Class
  401.       HWND        hwnd;                // Window Handle
  402.       MSG         msg;                 // Windows Message Pointer
  403.       static char buf[MAX_PATH];       // Temporary Buffer
  404.  
  405.       // Store the Global Application Instance Handle
  406.       hInst = hThisInst;
  407.  
  408.       // Define the Primary Windows Class
  409.       wclex.hInstance     = hInst;
  410.       wclex.lpszClassName = APPNAME;
  411.       wclex.lpfnWndProc   = WindowFunc;
  412.       wclex.style         = CS_HREDRAW | CS_VREDRAW;
  413.       wclex.cbSize        = sizeof( WNDCLASSEX );
  414.       wclex.hIcon         = LoadIcon( hThisInst, MAKEINTRESOURCE(IDI_JAGEMU));
  415.       wclex.hIconSm       = LoadIcon( hThisInst, MAKEINTRESOURCE(IDI_JAGEMU));
  416.       wclex.hCursor       = LoadCursor( NULL, IDC_ARROW );
  417.       wclex.lpszMenuName  = MAKEINTRESOURCE( IDR_MENU );
  418.       wclex.cbClsExtra    = 0;
  419.       wclex.cbWndExtra    = 0;
  420.       wclex.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
  421.  
  422.       // Register the Window Class
  423.       if( !RegisterClassEx( &wclex ) ) return( 0 );
  424.  
  425.       // Create the Main Application Window
  426.       wsprintf( buf, "%s - %s v%i.%i.%i",
  427.                 APPNAME, TITLE, MAJORREV, MINORREV, PATCHLVL );
  428.  
  429.       hwnd = CreateWindow( APPNAME, buf, WS_OVERLAPPEDWINDOW | 
  430.                            WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  431.                            50, 50, 600, 450, NULL, NULL, hInst, NULL );
  432.  
  433.       // Initialise the Common Controls Library 
  434.       InitCommonControls();
  435.  
  436.       // Display and Update the Application Window
  437.       ShowWindow( hwnd, nWinMode );
  438.       UpdateWindow( hwnd );
  439.  
  440.       // This is the Main Emulator Thread which will run in the background. By 
  441.       // default it loads an empty 'dummy' cartridge and does nothing. 
  442.       {
  443.          int mainthreadid;
  444.          mainthread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)EmuThread,
  445.                                     NULL, 0, &mainthreadid );
  446.       }
  447.  
  448.       // Windows Message Processing Loop
  449.       while( GetMessage( &msg, NULL, 0, 0 ) )
  450.       {
  451.          TranslateMessage( &msg );
  452.          DispatchMessage( &msg );
  453.       }
  454.  
  455.       GetTempPath( MAX_PATH, buf );    // Remove GL Information File
  456.       strcat( buf, "oglinfo" );
  457.       DeleteFile( buf );
  458.  
  459.       return( msg.wParam );            // Exit the Application
  460.    }
  461.