| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651 |
- /*
- ** Command & Conquer Red Alert(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***************************************************************************
- ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
- ***************************************************************************
- * *
- * Project Name : LIBRARY *
- * *
- * File Name : VIDEO.C *
- * *
- * Programmer : David Dettmer *
- * *
- * Last Update : June 29, 1995 [PWG] *
- * *
- *-------------------------------------------------------------------------*
- * Functions: *
- * Find_Video_Mode -- Converts a dos video mode to a WWLIB video mode *
- * Get_Video_Mode -- Returns the current video mode. *
- * Set_Video_Mode -- Sets the requested video mode *
- * Set_Lores_Function_Pointers -- Sets up the lowres function pointers *
- * Set_HiRes_Function_Pointers -- Sets the HiRes function pointers *
- * Set_Original_Video_Mode -- sets mode to restore system to on exit *
- * Get_Original_Video_Mode -- Gets the original video mode value *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include <dos.h>
- #include "iostream.h"
- #include "video.h"
- #include "descmgmt.h"
- #include "mcgaprim.h"
- #include "gbuffer.h"
- #include "vbuffer.h"
- #include "wwmem.h"
- #include "playcd.h"
- extern "C" int MInstalled ;
- extern "C" void Hide_Mouse(void);
- extern "C" void Show_Mouse(void);
- extern "C" void Reset_Mouse (void) ;
- extern "C" int Vesa_Hook ( REALPTR function ) ;
- extern "C" void Remove_Vesa (void) ;
- extern "C" SEGSEL RMVesaVectorSel ;
- extern "C" REALPTR VesaFunc;
- /*=========================================================================*/
- /* Define the global variables that we require. */
- /*=========================================================================*/
- long BankTable[MAX_BANK_ENTRIES];
- int GraphicMode = UNINITIALIZED_MODE;
- long XRes = 0;
- long YRes = 0;
- REALPTR VesaFunc;
- unsigned long RMVesaVector ;
- unsigned long RMVesaRegs ;
- /*=========================================================================*
- * Private Varirables *
- * *
- * VInfo - Protected mode copy of VInfo structure. *
- * ModeInfo - Protected mode copy of ModeInfo structure. *
- * rpModeInfo - Real ptr to ModeInfo structure in conventional memory. *
- * rpVInfo - Real ptr to VInfo structure in conventional memory. *
- * _regs - Registers used for calling software interrupts. *
- *=========================================================================*/
- PRIVATE void * rpModeInfo = NULL;
- PRIVATE SEGSEL rpModeInfoSel ;
- PRIVATE void * rpVInfo = NULL;
- PRIVATE SEGSEL rpVInfoSel ;
- PRIVATE long _OriginalVideoMode = UNINITIALIZED_MODE;
- PRIVATE VesaInfoType VInfo;
- PRIVATE VesaModeInfoType ModeInfo;
- /*=========================================================================*/
- /* The following PRIVATE functions are in this file: */
- /*=========================================================================*/
- PRIVATE long Install_Vesa(void);
- PRIVATE long Vesa_Get_Mode_Info(long mode);
- PRIVATE long Vesa_Set_Mode(long mode);
- PRIVATE void Init_Bank_Table(void);
- PRIVATE VOID Set_LoRes_Function_Pointers(VOID);
- PRIVATE VOID Set_HiRes_Function_Pointers(VOID);
- extern "C" long Vesa_XRes(void);
- extern "C" long Vesa_YRes(void);
- extern "C" char CurrentPalette [ 256 * 3 ] ;
- extern "C" char PaletteTable [ 1024 ] ;
- /*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
- /***************************************************************************
- * GET_VIDEO_MODE -- Returns the current video mode. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: returns the graphic mode as a WWLIB library define *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 01/25/1994 : Created. *
- *=========================================================================*/
- int Get_Video_Mode(void)
- {
- union REGS regs;
- if( GraphicMode == UNINITIALIZED_MODE )
- {
- regs . x . eax = 0xf00 ; // get graphic mode
- int386 ( 0x10 , & regs , & regs ) ;
- return ( regs . w . ax & 0xff ) ;
- }
- return(GraphicMode); // return the graphic mode
- }
- /***************************************************************************
- * Install_Vesa -- Initializes the vesa driver if it exists *
- * *
- * INPUT: none *
- * *
- * OUTPUT: return -1 if error/VESA not supported. *
- * *
- * WARNINGS: This function will not work unless a vesa compatable driver *
- * is installed in either hardware or software. *
- * *
- * HISTORY: *
- * 11/21/1994 PWG : Created. *
- *=========================================================================*/
- PRIVATE long Install_Vesa(void)
- {
- UINT paras;
- USHORT longest ;
- union REGS regs;
- struct SREGS sregs;
- /* Calculate size of VesaInfo structure in paragraphs */
- paras = ( sizeof(VesaInfoType) + 15 ) >> 4 ;
-
- /* Allocate real-mode memory for VESA structure. */
- if ( DPMI_real_alloc ( paras , & rpVInfoSel , & longest ) ) return - 1 ;
- rpVInfo = ( void * ) ( rpVInfoSel . seg << 4 ) ;
- /* Calculate size of VesaModeInfo structure in paragraphs */
- paras = ( sizeof(VesaModeInfoType) + 15 ) >> 4 ;
- /* Allocate real-mode memory for VESA structure. */
- if ( DPMI_real_alloc ( paras , & rpModeInfoSel , & longest ) )
- {
- Remove_Vesa();
- return (-1);
- }
- rpModeInfo = ( void * ) ( rpModeInfoSel . seg << 4 ) ;
- /* Clear the input buffer */
- memset ( rpVInfo , 0 , sizeof ( VesaInfoType) ) ;
-
- /* Read Vesa information */
- regs . x . eax = 0x4f00 ;
- regs . x . edi = 0 ;
- sregs . es = rpVInfoSel . seg ;
- DPMI_real_intr ( 0x10 , & regs , & sregs );
- regs . x . eax &= 0xffff ;
- if ( regs . x . eax != 0x004F) return (-1);
- Mem_Copy ( rpVInfo , & VInfo , sizeof(VesaInfoType)) ;
- return 0;
- }
- /***************************************************************************
- * VESA_GET_MODE_INFO -- Gets info about specified video mode *
- * *
- * INPUT: long - the mode we are requesting info about *
- * *
- * OUTPUT: long - 0 if sucessful, -1 if failure *
- * *
- * HISTORY: *
- * 11/21/1994 PWG : Created. *
- *=========================================================================*/
- PRIVATE long Vesa_Get_Mode_Info(long mode)
- {
- union REGS regs;
- struct SREGS sregs;
- if (rpModeInfo )
- {
- /* Clear the input buffer */
- memset ( rpModeInfo, 0, sizeof(VesaModeInfoType));
- /* Set up function call */
- regs . x . eax = 0x4F01;
- regs . x . ecx = mode;
- regs . x . edi = 0 ;
- sregs . es = rpModeInfoSel . seg ;
- DPMI_real_intr ( 0x10 , & regs , & sregs );
- regs . x . eax &= 0xffff ;
- if ( regs . x . eax == 0x004F)
- {
- Mem_Copy ( rpModeInfo , &ModeInfo , sizeof(VesaModeInfoType));
- // this part is only temporary until Phil get the documentation
- // for DPMI funtion 0x301 simulate real call
- // in the mean time we will be making call to the vesa driver
- // thru a real interrupt
- if ( Vesa_Hook ( ModeInfo . WinFunc ) ) return ( -1 ) ;
- return (0);
- }
- }
- return (-1);
- }
- /***************************************************************************
- * VESA_SET_MODE -- Sets the specified Vesa mode *
- * *
- * INPUT: long - the mode we wish to set *
- * *
- * OUTPUT: long - 0 if all is ok, -1 if we cannot set this mode *
- * *
- * WARNINGS: You must call Install_Vesa before calling Vesa_Set_Mode *
- * *
- * HISTORY: *
- * 11/21/1994 PWG : Created. *
- *=========================================================================*/
- PRIVATE long Vesa_Set_Mode(long mode)
- {
- union REGS regs;
- struct SREGS sregs;
- /* Get mode info */
- if ( Vesa_Get_Mode_Info(mode) ) return (-1) ;
- if ((ModeInfo.Attributes & 0x01) == 0) return (-1);
- /* Set vesa VIDEO MODE */
- regs . x . eax = 0x4F02; //
- regs . x . ebx = mode;
- int386 ( 0x10 , & regs , & regs ) ;
- // delay ( 1000 ) ;
- if ( VInfo . Capabilities & 1 )
- {
- /* Set DAC to 6 bit per color register */
- regs . x . eax = 0x4F08;
- regs . h . bl = 0;
- regs . h . bh = 6 ;
- int386 ( 0x10 , & regs , & regs ) ;
- // delay ( 1000 ) ;
- }
- regs . x . eax &= 0xffff ;
- if ( regs . x . eax != 0x004F) return (-1);
- Init_Bank_Table();
- return (0);
- }
- /***************************************************************************
- * VESA_XRES -- Returns horizontal resolution of vesa mode *
- * *
- * INPUT: none *
- * *
- * OUTPUT: long - the horizontal resolution of vesa mode *
- * *
- * WARNINGS: You must call Install_Vesa and Vesa_Set_Mode before calling *
- * Vesa_XRes(). *
- * *
- * HISTORY: *
- * 11/21/1994 PWG : Created. *
- *=========================================================================*/
- long Vesa_XRes(void)
- {
- return ((long)ModeInfo.XRes);
- }
- /***************************************************************************
- * VESA_YRES -- Returns vertical resolution of a vesa mode *
- * *
- * INPUT: none *
- * *
- * OUTPUT: long - the horizontal resolution of vesa mode *
- * *
- * WARNINGS: You must call Install_Vesa and Vesa_Set_Mode before calling *
- * Vesa_XRes(). *
- * *
- * HISTORY: *
- * 11/21/1994 PWG : Created. *
- *=========================================================================*/
- long Vesa_YRes(void)
- {
- return ((long)ModeInfo.YRes);
- }
- /***************************************************************************
- * INIT_BANK_TABLE -- Initializes the values in the bank table *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 12/02/1994 PWG : Created. *
- *=========================================================================*/
- PRIVATE void Init_Bank_Table(void)
- {
- long size,bankval;
- int num_banks,lp;
- union REGS regs;
- struct SREGS sregs;
- size = Vesa_XRes() * Vesa_YRes(); // get video mode size
- num_banks = size / 65536; // get number of banks
- if (size % 65536) // adjust number of banks if
- num_banks++; // they dont break evenly
- bankval = 64 / ModeInfo.WinGranularity;
- VesaFunc = ModeInfo.WinFunc;
- for (lp = 0; lp < num_banks; lp++)
- BankTable[lp] = lp * bankval;
- regs . x . eax = 0x4F05; // Reset Vesa to Point to Bank 0
- regs . x . ebx = 0x0000;
- regs . x . edx = 0x0000;
- int386 ( 0x10 , & regs , & regs ) ;
- }
- /***************************************************************************
- * SET_MODE -- Used to set a graphic mode *
- * *
- * INPUT: int - the mode that we are setting *
- * *
- * OUTPUT: int - FALSE if failure, TRUE otherwise *
- * *
- * HISTORY: *
- * 11/21/1994 PWG : Created. *
- *=========================================================================*/
- int Set_Video_Mode(int mode)
- {
- union REGS inregs,outregs;
- static first_time = 0 ;
- int oldmode ;
-
- /*======================================================================*/
- /* If this is the first time we have set the mode we need to store */
- /* of the original mode. */
- /*======================================================================*/
- if ( ! first_time ) {
- first_time = 1 ;
- Set_Original_Video_Mode(Get_Video_Mode());
- }
-
- /*======================================================================*/
- /* If the mode we are trying to set is mode zero than we are actually */
- /* trying to restore the system to its original video mode. */
- /*======================================================================*/
- if (mode == RESET_MODE)
- mode = Get_Original_Video_Mode(); // set mode properly
- if (mode == GraphicMode) // if mode already correct
- return(TRUE); // get out of here
- oldmode = GraphicMode ;
- GraphicMode = mode ;
- /**********************************************************************/
- /* make sure the mouse is term off before any change */
- /*********************************************************************/
- if ( MInstalled == TRUE ) Hide_Mouse () ;
- /* clear color palette */
- memset ( CurrentPalette , 255 , sizeof ( CurrentPalette ) ) ;
- memset ( PaletteTable , 0 , sizeof ( PaletteTable ) ) ;
- /*======================================================================*/
- /* If we are currently in a vesa mode, free it up so that we can do it */
- /* again. */
- /*======================================================================*/
- if ((oldmode >= VESA_MIN) && (oldmode <= VESA_MAX))
- Remove_Vesa();
- /*======================================================================*/
- /* If we are requesting a vesa mode, than use the vesa calls to handle */
- /* it. */
- /*======================================================================*/
- if ( GraphicMode >= VESA_MIN && GraphicMode <= VESA_MAX)
- {
- inregs . x . eax = MCGA_MODE;
- int386 ( 0x10 , &inregs , &outregs);
- // delay ( 1000 ) ;
- if ( Install_Vesa () != 0 ) {
- Set_Video_Mode(oldmode);
- return(FALSE);
- }
- if (Vesa_Set_Mode(GraphicMode) != 0)
- {
- Set_Video_Mode(oldmode);
- return(FALSE);
- }
- XRes = Vesa_XRes();
- YRes = Vesa_YRes();
- Set_HiRes_Function_Pointers();
- }
- else
- {
- /*===================================================================*/
- /* If not a vesa mode, then handle that as well. */
- /*===================================================================*/
- inregs . x . eax = GraphicMode ;
- int386( 0x10, &inregs, &outregs);
- // delay ( 1000 ) ;
- if ( GraphicMode == MCGA_MODE ) {
- XRes = 320;
- YRes = 200;
- Set_LoRes_Function_Pointers();
- }
- }
- if ( MInstalled == TRUE ) {
- Reset_Mouse () ;
- Show_Mouse () ;
- }
- return(TRUE);
- }
- /***************************************************************************
- * VESA_INFO -- Debug routine which displays vesa info to stdout *
- * *
- * INPUT: none *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: Must call Install_Vesa before attempting to get the vesa *
- * info. *
- * *
- * HISTORY: *
- * 11/22/1994 PWG : Created. *
- *=========================================================================*/
- void Vesa_Info(void)
- {
- cout << "Attributes: " << (long)ModeInfo.Attributes << "\n"
- << "Win A Attributes: " << (long)ModeInfo.WinA_Attributes << "\n"
- << "Win B Attributes: " << (long)ModeInfo.WinB_Attributes << "\n"
- << "Win Granularity " << (long)ModeInfo.WinGranularity << "\n"
- << "Win Size: " << (long)ModeInfo.WinSize << "\n"
- << "Win A Segment: " << hex << (unsigned short)ModeInfo.WinA_Segment << "\n"
- << "Win B Segment: " << (unsigned short)ModeInfo.WinB_Segment << "\n"
- << "Bytes per scan line: " << dec << (unsigned short)ModeInfo.BytesPerScanline << "\n"
- << "X resolution: " << (long)ModeInfo.XRes << "\n"
- << "Y resolution: " << (long)ModeInfo.YRes << "\n"
- << "X Char Size: " << (long)ModeInfo.XCharSize << "\n"
- << "Y Char Size: " << (long)ModeInfo.YCharSize << "\n"
- << "Number of planes: " << (long)ModeInfo.NumPlanes << "\n"
- << "Bits per pixels: " << (long)ModeInfo.BitsPerPixel << "\n"
- << "Number of Banks: " << (long)ModeInfo.NumBanks << "\n"
- << "Memory Model: " << (long)ModeInfo.MemoryModel << "\n"
- << "Bank Size: " << (long)ModeInfo.BankSize << "\n";
- }
- /***************************************************************************
- * VESA_SET_WINDOW -- Sets given vesa window to given grain *
- * *
- * INPUT: int window - 0 for window A, 1 for window B *
- * int grain - the granularity point for window *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 12/05/1994 PWG : Created. *
- *=========================================================================*/
- void Vesa_Set_Window(long grain_num)
- {
- union REGS regs;
- struct SREGS sregs;
- regs . x . eax = 0x4f05 ;
- regs . x . ebx = 0 ;
- regs . x . edx = grain_num;
- // DPMI_real_call ( ModeInfo.WinFunc , & regs , & sregs ) ;
- DPMI_real_intr ( VesaFunc , & regs , & sregs ) ;
- }
- /***************************************************************************
- * SET_LORES_FUNCTION_POINTERS -- Sets up the lowres function pointers *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 01/12/1995 PWG : Created. *
- *=========================================================================*/
- PRIVATE VOID Set_LoRes_Function_Pointers(VOID)
- {
- VVPC_Clear_Func = MCGA_Clear;
- VVPC_To_Buffer_Func = MCGA_To_Buffer;
- VVPC_Put_Pixel_Func = MCGA_Put_Pixel;
- VVPC_Get_Pixel_Func = MCGA_Get_Pixel;
- GVPC_Blit_to_VVPC_Func = Linear_Blit_To_Linear;
- VVPC_Blit_to_GVPC_Func = Linear_Blit_To_Linear;
- VVPC_Blit_to_VVPC_Func = Linear_Blit_To_Linear;
- VVPC_Buffer_To_Page = MCGA_Buffer_To_Page;
- GVPC_Scale_To_VVPC = Linear_Scale_To_Linear;
- VVPC_Scale_To_GVPC = Linear_Scale_To_Linear;
- VVPC_Scale_To_VVPC = Linear_Scale_To_Linear;
- VVPC_Print_Func = MCGA_Print;
- }
- /***************************************************************************
- * SET_HIRES_FUNCTION_POINTERS -- Sets the HiRes function pointers *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 01/12/1995 PWG : Created. *
- *=========================================================================*/
- PRIVATE VOID Set_HiRes_Function_Pointers(VOID)
- {
- VVPC_Clear_Func = Vesa_Clear;
- VVPC_To_Buffer_Func = Vesa_To_Buffer;
- VVPC_Put_Pixel_Func = Vesa_Put_Pixel;
- VVPC_Get_Pixel_Func = Vesa_Get_Pixel;
- GVPC_Blit_to_VVPC_Func = Linear_Blit_To_Vesa;
- VVPC_Blit_to_GVPC_Func = Vesa_Blit_To_Linear;
- VVPC_Blit_to_VVPC_Func = Vesa_Blit_To_Vesa;
- VVPC_Buffer_To_Page = Vesa_Buffer_To_Page;
- GVPC_Scale_To_VVPC = Linear_Scale_To_Vesa;
- VVPC_Scale_To_GVPC = Vesa_Scale_To_Linear;
- VVPC_Scale_To_VVPC = Vesa_Scale_To_Vesa;
- VVPC_Print_Func = Vesa_Print;
- }
- /***************************************************************************
- * Update_Video_Mode -- used to reprogram the current graphic mode afte *
- * a task swicthing from windows *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * HISTORY: *
- * 03/18/94 JRJ : Created. *
- *=========================================================================*/
- void Update_Video_Mode (void)
- {
- union REGS inregs,outregs;
- /* clear color palette */
- memset ( CurrentPalette , 255 , sizeof ( CurrentPalette ) ) ;
- memset ( PaletteTable , 0 , sizeof ( PaletteTable ) ) ;
-
- /**********************************************************************/
- /* make sure the mouse is term off before any change */
- /*********************************************************************/
- if ( MInstalled == TRUE )
- Hide_Mouse () ;
- /*======================================================================*/
- /* If we are requesting a vesa mode, than use the vesa calls to handle */
- /* it. */
- /*======================================================================*/
- if ( GraphicMode >= VESA_MIN && GraphicMode <= VESA_MAX) {
- inregs . x . eax = MCGA_MODE;
- int386 ( 0x10 , &inregs , &outregs);
- Vesa_Set_Mode(GraphicMode);
- }
- else {
- /*===================================================================*/
- /* If not a vesa mode, then handle that as well. */
- /*===================================================================*/
- inregs . x . eax = GraphicMode ;
- int386( 0x10, &inregs, &outregs);
- }
- if ( MInstalled == TRUE ) {
- Reset_Mouse () ;
- Show_Mouse () ;
- }
- }
- /***************************************************************************
- * SET_ORIGINAL_VIDEO_MODE -- sets mode to restore system to on exit *
- * *
- * INPUT: int video mode number *
- * *
- * OUTPUT: none *
- * *
- * HISTORY: *
- * 06/29/1995 PWG : Created. *
- *=========================================================================*/
- void Set_Original_Video_Mode(int mode)
- {
- _OriginalVideoMode = mode;
- }
- /***************************************************************************
- * GET_ORIGINAL_VIDEO_MODE -- Gets the original video mode value *
- * *
- * INPUT: none *
- * *
- * OUTPUT: int the video mode set when we entered *
- * *
- * HISTORY: *
- * 06/29/1995 PWG : Created. *
- *=========================================================================*/
- int Get_Original_Video_Mode(void)
- {
- return(_OriginalVideoMode);
- }
|