home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / 2d / vesalib.c < prev    next >
Text File  |  1998-06-08  |  9KB  |  279 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: f:/miner/source/2d/rcs/vesalib.c $
  15.  * $Revision: 1.3 $
  16.  * $Author: john $
  17.  * $Date: 1994/11/07 12:07:42 $
  18.  * 
  19.  * Routines to access VESA video modes.
  20.  * 
  21.  * $Log: vesalib.c $
  22.  * Revision 1.3  1994/11/07  12:07:42  john
  23.  * Made save/restore cursor work a bit better.
  24.  * 
  25.  * Revision 1.2  1994/09/29  10:09:26  john
  26.  * Initial version, but not used.
  27.  * 
  28.  * Revision 1.1  1994/09/19  11:54:45  john
  29.  * Initial revision
  30.  * 
  31.  * 
  32.  */
  33.  
  34.  
  35. #pragma off (unreferenced)
  36. static char rcsid[] = "$Id: vesalib.c 1.3 1994/11/07 12:07:42 john Exp $";
  37. #pragma on (unreferenced)
  38.  
  39.  
  40. #include "dpmi.h"
  41.  
  42. typedef struct VgaInfoBlock {
  43.     char                VESASignature[4];        // 4 signature bytes
  44.     ushort            VESAVersion;            // VESA version number
  45.     ushort            OEMStringPtrOffset;    // Pointer to OEM string
  46.     ushort            OEMStringPtrSegment;    // Pointer to OEM string
  47.     uint                Capabilities;            // Capabilities of the video environment
  48.     ushort            VideoModePtrOffset;    // Pointer to supported Super VGA modes
  49.     ushort            VideoModePtrSegment;    // Pointer to supported Super VGA modes
  50.     ushort            TotalMemory;            // Number of 64K memory blocks on board
  51.     ubyte                Reserved[242];            //    Reserved for future use.
  52. } VgaInfoBlock;
  53.  
  54. typedef struct ModeInfoBlock {
  55.     ushort            ModeAttributes;
  56.     ubyte                WinAAttributes;
  57.     ubyte                WinBAttributes;
  58.     ushort            WinGranularity;
  59.     ushort            WinSize;
  60.     ushort            WinASegment;
  61.     ushort            WinBSegment;
  62.     ushort            WinFuncPtrOffset;
  63.     ushort            WinFuncPtrSegment;
  64.     ushort            BytesPerScanLine;
  65.  
  66.     ushort            Xresolution;
  67.     ushort            Yresolution;
  68.     ubyte                Xcharsize;
  69.     ubyte                Ycharsize;
  70.     ubyte                NumberOfPlanes;
  71.     ubyte                BitsPerPixel;
  72.     ubyte                NumberOfBanks;
  73.     ubyte                MemoryModel;
  74.     ubyte                BankSize;
  75.     ubyte                dummy[227];
  76. } ModeInfoBlock;
  77.  
  78. //  0=Mode set OK
  79. //  1=No VGA adapter installed
  80. //  2=Program doesn't support this VESA granularity
  81. //  3=Monitor doesn't support that VESA mode.:
  82. //  4=Video card doesn't support that VESA mode.
  83. //  5=No VESA driver found.
  84. //  6=Bad Status after VESA call/
  85. //  7=Not enough DOS memory to call VESA functions.
  86. //  8=Error using DPMI.
  87. //  9=Error setting logical line width.
  88. // 10=Error allocating selector for A0000h
  89. // 11=Not a valid mode support by gr.lib
  90. // Returns one of the above without setting mode
  91.  
  92. void *pDosBuffer=NULL;
  93. VgaInfoBlock vesa_info_block;
  94. ModeInfoBlock vesa_mode_info_block;
  95. ushort RealSelector;
  96. ushort * SupportedModes=NULL;
  97.  
  98. short gr_vesa_check_mode(short mode)
  99. {
  100.     dpmi_real_regs    rr;
  101.  
  102.     if(pDosBuffer==NULL)    {
  103.         pDosBuffer = dpmi_real_malloc( 256, &RealSelector );
  104.         if (!pDosBuffer)
  105.             Error( "Error allocating DOS buffer" );
  106.     }
  107.     memset( &rr, 0, sizeof(dpmi_real_regs);        // Clear real registers...
  108.     rr.eax = 0x4f00;    // Return SuperVGA information
  109.     rr.es = DPMI_real_segment(pDosBuffer);
  110.     rr.edi = DPMI_real_offset(pDosBuffer);
  111.     
  112.     dpmi_real_int386( 0x10, &rr );
  113.                                     
  114.     if ((rr.eax & 0xffff) != 0x4f )    {
  115.         return 5;        // No VESA driver found                                        
  116.     }
  117.         
  118.     memcpy( &vesa_info_block, pDosBuffer, sizeof(VgaInfoBlock) );
  119.                     
  120.     // Make sure there is a VESA signature
  121.     if (!memcmp( vesa_info_block.VESASignature, "VESA" ))
  122.         return 5;            // No VESA driver found
  123.  
  124.     // We now have a valid VESA driver loaded, so search through the
  125.     // list of supported modes, searching for the mode we want.
  126.     SupportedModes    = (ushort *)((vesa_info_block.VideoModePtrSegment*16)+vesa_info_block.VideoModePtrOffset);
  127.         
  128.     while( *SupportedModes != 0xffff )    {
  129.         if (*SupportedModes==mode)    {
  130.             break;
  131.         }    
  132.         SupportedModes++;
  133.     }
  134.     if (*SupportedModes!=mode)    {
  135.         return 4;        // Video card doesn't support that VESA mode.
  136.     }
  137.             
  138.     memset( &rr, 0, sizeof(dpmi_real_regs);        // Clear real registers...
  139.     rr.eax = 0x4f01;    // Return SuperVGA mode information
  140.     rr.ecx = mode;        // Super VGA video mode
  141.     rr.es = DPMI_real_segment(pDosBuffer);
  142.     rr.edi = DPMI_real_offset(pDosBuffer);
  143.     
  144.     dpmi_real_int386x( 0x10, &rr );
  145.                             
  146.     if ((rr.eax & 0xffff) != 0x4f )    {
  147.         return 5;        // No VESA driver found                                        
  148.     }
  149.  
  150.     memcpy( &vesa_mode_info_block, pDosBuffer, sizeof(ModeInfoBlock) );
  151.     
  152.     if (!(vesa_mode_info_block.ModeAttributes&1) )    {
  153.         return 3;        // Monitor doesn't support this mode.
  154.     }
  155.  
  156.     switch( vesa_mode_info_block.WinGranularity )    {
  157.     case 64:    PageSizeShift = 0; break;
  158.     case 32:    PageSizeShift = 1; break;
  159.     case 16:    PageSizeShift = 2; break;
  160.     case 8:    PageSizeShift = 3; break;
  161.     case 4:    PageSizeShift = 4; break;
  162.     case 2:    PageSizeShift = 5; break;
  163.     case 1:    PageSizeShift = 6; break;
  164.     default:    
  165.         return 2;        // Granularity not supported.
  166.     }
  167.     
  168.     return 0;
  169. }
  170.  
  171. typedef struct VgaInfoBlock {
  172.     char                VESASignature[4];        // 4 signature bytes
  173.     ushort            VESAVersion;            // VESA version number
  174.     ushort            OEMStringPtrOffset;    // Pointer to OEM string
  175.     ushort            OEMStringPtrSegment;    // Pointer to OEM string
  176.     uint                Capabilities;            // Capabilities of the video environment
  177.     ushort            VideoModePtrOffset;    // Pointer to supported Super VGA modes
  178.     ushort            VideoModePtrSegment;    // Pointer to supported Super VGA modes
  179.     ushort            TotalMemory;            // Number of 64K memory blocks on board
  180.     ubyte                Reserved[242];            //    Reserved for future use.
  181. } VgaInfoBlock;
  182.  
  183. void * gr_save_mode_vesa()
  184. {
  185.     void * pDosBuffer;
  186.     ushort DosSelector;
  187.     dpmi_real_regs    rr;
  188.     VgaInfoBlock vesa_info_block;
  189.     int save_size;
  190.     
  191.     pDosBuffer = dpmi_real_malloc(sizeof(VgaInfoBlock), &DosSelector);
  192.     if (!pDosBuffer)
  193.         return NULL;
  194.  
  195.     memset( &rr, 0, sizeof(dpmi_real_regs));        // Clear real registers...
  196.     rr.eax = 0x4f00;    // Return SuperVGA information
  197.     rr.es = DPMI_real_segment(pDosBuffer);
  198.     rr.edi = DPMI_real_offset(pDosBuffer);
  199.     dpmi_real_int386x( 0x10, &rr );
  200.  
  201.     memcpy( &vesa_info_block, pDosBuffer, sizeof(VgaInfoBlock) );
  202.     dpmi_real_free(DosSelector);
  203.     if ((rr.eax & 0xffff) != 0x4f )    {
  204.         return NULL;        // No VESA driver found                                        
  205.     }
  206.     // Make sure there is a VESA signature
  207.     if (!memcmp( vesa_info_block.VESASignature, "VESA", 4 ))
  208.         return NULL;            // No VESA driver found
  209.     
  210.     memset( &rr, 0, sizeof(dpmi_real_regs));        // Clear real registers...
  211.     rr.eax = 0x4f04;    // Save/Restore SuperVGA video state
  212.     rr.edx = 00;        // Return save/restore buffer size
  213.     rr.ecx = 0xf;        // Save all states
  214.     dpmi_real_int386x( 0x10, &rr );
  215.     if ((rr.eax & 0xffff) != 0x4f )    {
  216.         return NULL;        // No VESA driver found                                        
  217.     }
  218.     save_size = (rr.ebx & 0xffff)*64;        // How many bytes save buffer requires...
  219.  
  220.     pDosBuffer = dpmi_real_malloc(save_size, &DosSelector);
  221.     if (!pDosBuffer)
  222.         return NULL;
  223.  
  224.     memset( &rr, 0, sizeof(dpmi_real_regs));        // Clear real registers...
  225.     rr.eax = 0x4f04;    // Save/Restore SuperVGA video state
  226.     rr.edx = 1;            // Save video state
  227.     rr.ecx = 0xf;        // Save all states
  228.  
  229.     rr.es = DPMI_real_segment(pDosBuffer);
  230.     rr.ebx = DPMI_real_offset(pDosBuffer);
  231.     dpmi_real_int386x( 0x10, &rr );
  232.     if ((rr.eax & 0xffff) != 0x4f )    {
  233.         dpmi_real_free(DosSelector);
  234.         return NULL;        // No VESA driver found                                        
  235.     }
  236.     gr_restore_mode_vesa( pDosBuffer );
  237.     return pDosBuffer;
  238. }
  239.  
  240. void gr_restore_mode_vesa(void * buffer)
  241. {
  242.     void * pDosBuffer;
  243.     ushort DosSelector;
  244.     dpmi_real_regs    rr;
  245.     VgaInfoBlock vesa_info_block;
  246.     
  247.     pDosBuffer = dpmi_real_malloc(sizeof(VgaInfoBlock), &DosSelector);
  248.     if (!pDosBuffer)
  249.         return;
  250.  
  251.     memset( &rr, 0, sizeof(dpmi_real_regs));        // Clear real registers...
  252.     rr.eax = 0x4f00;    // Return SuperVGA information
  253.     rr.es = DPMI_real_segment(pDosBuffer);
  254.     rr.edi = DPMI_real_offset(pDosBuffer);
  255.     dpmi_real_int386x( 0x10, &rr );
  256.  
  257.     memcpy( &vesa_info_block, pDosBuffer, sizeof(VgaInfoBlock) );
  258.     dpmi_real_free(DosSelector);
  259.     if ((rr.eax & 0xffff) != 0x4f )    {
  260.         return;        // No VESA driver found                                        
  261.     }
  262.     // Make sure there is a VESA signature
  263.     if (!memcmp( vesa_info_block.VESASignature, "VESA", 4 ))
  264.         return;            // No VESA driver found
  265.     
  266.     memset( &rr, 0, sizeof(dpmi_real_regs));        // Clear real registers...
  267.     rr.eax = 0x4f04;    // Save/Restore SuperVGA video state
  268.     rr.edx = 2;            // Restore video state
  269.     rr.ecx = 0xf;        // Save all states
  270.     rr.es = DPMI_real_segment(buffer);
  271.     rr.ebx = DPMI_real_offset(buffer);
  272.     dpmi_real_int386x( 0x10, &rr );
  273.     if ((rr.eax & 0xffff) != 0x4f )    {
  274.         return;        // No VESA driver found                                        
  275.     }
  276.     return;
  277. }
  278. 
  279.