mirror of
https://github.com/electronicarts/CnC_Red_Alert.git
synced 2025-12-15 23:21:40 -05:00
Initial commit of Command & Conquer Red Alert source code.
This commit is contained in:
457
WINVQ/VQM32/VESAVID.CPP
Normal file
457
WINVQ/VQM32/VESAVID.CPP
Normal file
@@ -0,0 +1,457 @@
|
||||
/*
|
||||
** 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 S T U D I O S
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*
|
||||
* FILE
|
||||
* vesavid.c
|
||||
*
|
||||
* DESCRIPTION
|
||||
* VESA video manager. (32-Bit protected mode)
|
||||
*
|
||||
* PROGRAMMER
|
||||
* Denzil E. Long, Jr.
|
||||
*
|
||||
* DATE
|
||||
* January 26, 1995
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*
|
||||
* PUBLIC
|
||||
* InitVESA - Initialize the VESA video manager.
|
||||
* UninitVESA - Uninitialize the VESA video manager.
|
||||
* SetVESAMode - Set the display to the specified VESA video mode.
|
||||
* ReadVESAModeInfo - Read the VESA mode information from the video card.
|
||||
* SetVESAWindow - Set VESA window A's start address.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <mem.h>
|
||||
#include <dos.h>
|
||||
|
||||
#ifndef __WATCOMC__
|
||||
#include <pldos32.h>
|
||||
#include <pharlap.h>
|
||||
#else
|
||||
#include "realmode.h"
|
||||
#endif
|
||||
|
||||
#include "vesavid.h"
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* PRIVATE DECLARATIONS
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
static short _VInfoSel = NULL;
|
||||
static short _VInfoSeg = NULL;
|
||||
static short _ModeInfoSel = NULL;
|
||||
static short _ModeInfoSeg = NULL;
|
||||
|
||||
#else /* __WATCOMC__ */
|
||||
/* _regs - Registers used for calling software interrupts.
|
||||
* _rpVInfo - Real pointer to VInfo structure in conventional memory.
|
||||
* _rpModeInfo - Real pointer to ModeInfo structure in conventional memory.
|
||||
* _VInfo - Protected mode copy of VInfo structure.
|
||||
* _ModeInfo - Protected mode copy of ModeInfo structure.
|
||||
*/
|
||||
static SWI_REGS _regs;
|
||||
static REALPTR _rpVInfo = NULL;
|
||||
static REALPTR _rpModeInfo = NULL;
|
||||
static VESAInfo _VInfo;
|
||||
static VESAModeInfo _ModeInfo;
|
||||
|
||||
#endif /* __WATCOMC__ */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* InitVESA - Initialize the VESA video manager.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* Error = InitVESA()
|
||||
*
|
||||
* long InitVESA(void);
|
||||
*
|
||||
* FUNCTION
|
||||
* Initialize the VESA video system. Get the VESA information from the
|
||||
* VESA video bios.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* Error - 0 if successful, or -1 error/VESA not supported.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
long InitVESA(void)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
union REGS r;
|
||||
struct SREGS sr;
|
||||
RMInfo rmi;
|
||||
long error = -1;
|
||||
|
||||
/* Allocate real-mode memory for VESA structure. */
|
||||
r.x.eax = 0x0100;
|
||||
r.x.ebx = (sizeof(VESAInfo) + 15) >> 4;
|
||||
int386(0x31, &r, &r);
|
||||
|
||||
if (r.x.cflag == 0) {
|
||||
_VInfoSel = r.w.dx;
|
||||
_VInfoSeg = r.w.ax;
|
||||
|
||||
/* Allocate real-mode memory for VESAModeInfo structure. */
|
||||
r.x.eax = 0x0100;
|
||||
r.x.ebx = (sizeof(VESAModeInfo) + 15) >> 4;
|
||||
int386(0x31, &r, &r);
|
||||
|
||||
if (r.x.cflag == 0) {
|
||||
_ModeInfoSel = r.w.dx;
|
||||
_ModeInfoSeg = r.w.ax;
|
||||
|
||||
/* Clear VESAInfo structure. */
|
||||
memset(MK_PTR(0, _VInfoSeg), 0, sizeof(VESAInfo));
|
||||
|
||||
/* Get VESA information. */
|
||||
memset(&rmi, 0, sizeof(RMInfo));
|
||||
rmi.eax = 0x4F00;
|
||||
rmi.edi = 0;
|
||||
rmi.es = _VInfoSeg;
|
||||
|
||||
segread(&sr);
|
||||
r.w.ax = 0x0300;
|
||||
r.h.bl = 0x10;
|
||||
r.h.bh = 0;
|
||||
r.w.cx = 0;
|
||||
sr.es = FP_SEG(&rmi);
|
||||
r.x.edi = FP_OFF(&rmi);
|
||||
int386x(0x31, &r, &r, &sr);
|
||||
|
||||
if ((r.x.cflag == 0) && (rmi.eax == 0x004F)) {
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (error != 0) {
|
||||
UninitVESA();
|
||||
}
|
||||
|
||||
return (error);
|
||||
|
||||
#else /* __WATCOMC__ */
|
||||
|
||||
unsigned short rseg;
|
||||
long paras;
|
||||
long error = -1;
|
||||
|
||||
/* Calculate size of VESAInfo structure in paragraphs */
|
||||
paras = (sizeof(VESAInfo) + 15) >> 4;
|
||||
|
||||
/* Allocate real-mode memory for VESA structure. */
|
||||
if (_dx_real_alloc(paras, (unsigned short *)&rseg,
|
||||
(unsigned short *)¶s) == 0) {
|
||||
|
||||
RP_SET(_rpVInfo, 0, rseg);
|
||||
|
||||
/* Calculate size of VESAModeInfo structure in paragraphs */
|
||||
paras = (sizeof(VESAModeInfo) + 15) >> 4;
|
||||
|
||||
/* Allocate real-mode memory for VESAModeInfo structure. */
|
||||
if (_dx_real_alloc(paras, (unsigned short *)&rseg,
|
||||
(unsigned short *)¶s) == 0) {
|
||||
|
||||
RP_SET(_rpModeInfo, 0, rseg);
|
||||
|
||||
/* Clear the input buffer */
|
||||
FillRealMem(_rpVInfo, 0, sizeof(VESAInfo));
|
||||
|
||||
/* Set up function call */
|
||||
_regs.eax = 0x4F00;
|
||||
_regs.edi = RP_OFF(_rpVInfo);
|
||||
_regs.es = RP_SEG(_rpVInfo);
|
||||
_dx_real_int(0x10, &_regs);
|
||||
|
||||
if (_regs.eax == 0x004F) {
|
||||
ReadRealMem(&_VInfo, _rpVInfo, sizeof(VESAInfo));
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error != 0) {
|
||||
UninitVESA();
|
||||
}
|
||||
|
||||
return (error);
|
||||
|
||||
#endif /* __WATCOMC__ */
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* UninitVESA - Uninitialize the VESA video manager.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* UninitVESA()
|
||||
*
|
||||
* void UninitVESA(void);
|
||||
*
|
||||
* FUNCTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void UninitVESA(void)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
union REGS r;
|
||||
|
||||
/* Free VESAInfo structure */
|
||||
if (_VInfoSeg != NULL) {
|
||||
r.x.eax = 0x0101;
|
||||
r.x.edx = _VInfoSel;
|
||||
int386(0x31, &r, &r);
|
||||
|
||||
_VInfoSeg = NULL;
|
||||
_VInfoSel = NULL;
|
||||
}
|
||||
|
||||
/* Free VESAModeInfo structure */
|
||||
if (_ModeInfoSeg != NULL) {
|
||||
r.x.eax = 0x0101;
|
||||
r.x.edx = _VInfoSel;
|
||||
int386(0x31, &r, &r);
|
||||
|
||||
_ModeInfoSeg = NULL;
|
||||
_ModeInfoSel = NULL;
|
||||
}
|
||||
|
||||
#else /* __WATCOMC__ */
|
||||
|
||||
/* Free VESAInfo structure */
|
||||
if (_rpVInfo != NULL) {
|
||||
_dx_real_free(RP_SEG(_rpVInfo));
|
||||
_rpVInfo = NULL;
|
||||
}
|
||||
|
||||
/* Free VESAModeInfo structure */
|
||||
if (_rpModeInfo != NULL) {
|
||||
_dx_real_free(RP_SEG(_rpModeInfo));
|
||||
_rpModeInfo = NULL;
|
||||
}
|
||||
#endif /* __WATCOMC__ */
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* SetVESAMode - Set the display adapter to the given VESA video mode.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* VESAModeInfo = SetVESAMode(Mode)
|
||||
*
|
||||
* VESAModeInfo *SetVESAMode(long);
|
||||
*
|
||||
* FUNCTION
|
||||
* Set the display adapter to the specified VESA video mode.
|
||||
*
|
||||
* INPUTS
|
||||
* Mode - VESA video mode to set the display to.
|
||||
*
|
||||
* RESULT
|
||||
* VESAModeInfo - Pointer to VESA mode information structure or NULL if
|
||||
* error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
VESAModeInfo *SetVESAMode(long mode)
|
||||
{
|
||||
VESAModeInfo *vminfo;
|
||||
|
||||
/* Get mode info */
|
||||
if ((vminfo = ReadVESAModeInfo(mode)) != NULL) {
|
||||
|
||||
/* If the mode is supported, set it. */
|
||||
if ((vminfo->Attributes & 0x01) != 0) {
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
{
|
||||
union REGS r;
|
||||
|
||||
r.x.eax = 0x4F02;
|
||||
r.x.ebx = mode;
|
||||
int386(0x10, &r, &r);
|
||||
|
||||
if (r.x.eax != 0x004F)
|
||||
vminfo = NULL;
|
||||
}
|
||||
|
||||
#else /* __WATCOMC__ */
|
||||
|
||||
/* Set up function call */
|
||||
_regs.eax = 0x4F02;
|
||||
_regs.ebx = mode;
|
||||
_dx_real_int(0x10, &_regs);
|
||||
|
||||
if (_regs.eax != 0x004F) {
|
||||
vminfo = NULL;
|
||||
}
|
||||
#endif /* __WATCOMC__ */
|
||||
}
|
||||
}
|
||||
|
||||
return (vminfo);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* ReadVESAModeInfo - Read the VESA mode information from the video card.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* VESAModeInfo = ReadVESAModeInfo(Mode)
|
||||
*
|
||||
* VESAModeInfo *ReadVESAModeInfo(long);
|
||||
*
|
||||
* FUNCTION
|
||||
* Read information about the specified mode from the VESA video BIOS.
|
||||
*
|
||||
* INPUTS
|
||||
* Mode - Mode ID to get information about.
|
||||
*
|
||||
* RESULT
|
||||
* VESAModeInfo - Pointer to VESA mode information structure or NULL if
|
||||
* error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
VESAModeInfo *ReadVESAModeInfo(long mode)
|
||||
{
|
||||
VESAModeInfo *vminfo = NULL;
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
union REGS r;
|
||||
struct SREGS sr;
|
||||
RMInfo rmi;
|
||||
|
||||
/* Make sure we have real-mode memory. */
|
||||
if (_ModeInfoSeg != NULL) {
|
||||
memset(MK_PTR(0, _ModeInfoSeg), 0, sizeof(VESAModeInfo));
|
||||
|
||||
/* Get mode information. */
|
||||
memset(&rmi, 0, sizeof(RMInfo));
|
||||
rmi.eax = 0x4F01;
|
||||
rmi.ecx = mode;
|
||||
rmi.edi = 0;
|
||||
rmi.es = _ModeInfoSeg;
|
||||
|
||||
segread(&sr);
|
||||
r.w.ax = 0x0300;
|
||||
r.w.bx = 0x0010;
|
||||
r.w.cx = 0;
|
||||
sr.es = FP_SEG(&rmi);
|
||||
r.x.edi = FP_OFF(&rmi);
|
||||
int386x(0x31, &r, &r, &sr);
|
||||
|
||||
if ((r.x.cflag == 0) && (rmi.eax == 0x004F)) {
|
||||
vminfo = (VESAModeInfo *)MK_PTR(0, _ModeInfoSeg);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* __WATCOMC__ */
|
||||
|
||||
/* Make sure we have real-mode memory. */
|
||||
if (_rpModeInfo != NULL) {
|
||||
|
||||
/* Clear the input buffer */
|
||||
FillRealMem(_rpModeInfo, 0, sizeof(VESAModeInfo));
|
||||
|
||||
/* Set up function call */
|
||||
_regs.eax = 0x4F01;
|
||||
_regs.ecx = mode;
|
||||
_regs.edi = RP_OFF(_rpModeInfo);
|
||||
_regs.es = RP_SEG(_rpModeInfo);
|
||||
_dx_real_int(0x10, &_regs);
|
||||
|
||||
if (_regs.eax == 0x004F) {
|
||||
ReadRealMem(&_ModeInfo, _rpModeInfo, sizeof(VESAModeInfo));
|
||||
vminfo = &_ModeInfo;
|
||||
}
|
||||
}
|
||||
#endif /* __WATCOMC__ */
|
||||
|
||||
return (vminfo);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* SetVESAWindow - Set VESA window A's start address.
|
||||
*
|
||||
* SYNOPSIS
|
||||
* Error = SetVESAWindow(GrainNum)
|
||||
*
|
||||
* long SetVESAWindow(long);
|
||||
*
|
||||
* FUNCTION
|
||||
* This function invokes the Window Function, whose address is provided
|
||||
* in the VESAModeInfo structure. The 'GrainNum' must be in granularity
|
||||
* units as specified in the ModeInfo structure.
|
||||
*
|
||||
* INPUTS
|
||||
* GrainNum - Granularity number to set window to.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void SetVESAWindow(long grain)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
#else /* __WATCOMC__ */
|
||||
|
||||
RMC_BLK regp;
|
||||
|
||||
regp.eax = 0x4F05;
|
||||
regp.ebx = 0x00;
|
||||
regp.edx = grain;
|
||||
_dx_call_real(_ModeInfo.WinFunc, ®p, 0);
|
||||
#endif /* __WATCOMC__ */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user