⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vesa.cpp

📁 djgpp bt878 capture for DOS
💻 CPP
字号:
#include "vesa.h"

VIDEO_VESA::VIDEO_VESA(void)
{
   addr = 0;
	
   info_block.AllocateMem(512);

   if(GetControllerInfo() == VESA_PASS)
   {
      if(GetVersion() >=  2.0)
         vesa20_support = TRUE;
      else
         vesa20_support = FALSE;

      ReadModeList();

      VESA_MODE_INFO_BLOCK vmib;
      
      for(int i=0; i<mode_list_length; i++)
      {
         GetModeInfo(mode_list[i].mode_number, &vmib);
         mode_list[i].width = vmib.XResolution;
         mode_list[i].height = vmib.YResolution;
         mode_list[i].bpp = vmib.BitsPerPixel;
         if(vmib.ModeAttributes & 0x80)
            mode_list[i].mode_number |= 0x4000;
      }
   }
   else
   {
      vesa20_support = FALSE;
      mode_list_length = 0;
   }
}

VIDEO_VESA::~VIDEO_VESA(void)
{
   if(addr != 0)
      free(addr);
}
         
int VIDEO_VESA::GetControllerInfo()
{
   __dpmi_regs regs;

   info_block.Set((DWORD)0x32454256);
#ifdef _DEBUG_
   printf("DOS MEM = 0x%08X\n",info_block.GetAddress());
   printf("  Offset = 0x%04X\n", info_block.GetOffset());
   printf("  Segment = 0x%04X\n", info_block.GetSegment());
#endif
   regs.d.eax = VESA_CONTROLLER_INFO;
   regs.x.es = info_block.GetSegment();
   regs.d.edi = info_block.GetOffset();
   __dpmi_int(VIDEO_INT_NUM, &regs);

   if(regs.h.al != 0x4f || regs.h.ah != 0 ||
      info_block.GetDWORD() != 0x41534556)
      return VESA_FAIL;
   else
      return VESA_PASS;
}


float VIDEO_VESA::GetVersion(void)
{
   BYTE version_num;
   BYTE rev_num;
   
   rev_num = info_block.GetBYTE(4);
   version_num = info_block.GetBYTE(5);

   return ((float)(version_num) + ((float)(rev_num)/10.0));
}


void VIDEO_VESA::ReadModeList(void)
{
   UWORD mode_num;
   int i = 0;

   mode_list_length = 0;

   do
   {
      mode_num = info_block.GetDosMemWORD(info_block.GetWORD(0x10),
         info_block.GetWORD(0xe) + i);
      i += 2;
      if(mode_num != 0xffff)
         mode_list[mode_list_length++].mode_number = mode_num;
   }while(mode_num != 0xffff && mode_list_length < MAX_VESA_MODES);
}

int VIDEO_VESA::GetModeInfo(int mode, VESA_MODE_INFO_BLOCK *vmib)
{
   __dpmi_regs regs;
   DOS_MEM dos_vmib(sizeof(VESA_MODE_INFO_BLOCK));

   /* get mode info */
   regs.d.eax = VESA_MODE_INFO;
   regs.d.ecx = mode & 0x3fff;
   regs.x.es = dos_vmib.GetSegment();
   regs.d.edi = dos_vmib.GetOffset();
   __dpmi_int(VIDEO_INT_NUM, &regs);

   if(regs.h.al != 0x4f || regs.h.ah != 0x0)
      return VESA_FAIL;

   dosmemget(dos_vmib.GetAddress(), sizeof(VESA_MODE_INFO_BLOCK), vmib);

   return VESA_PASS;
}


int VIDEO_VESA::GetMode(void)
{
   __dpmi_regs regs;

   /* get current mode */
   regs.d.eax = VESA_GET_MODE;
   __dpmi_int(VIDEO_INT_NUM, &regs);

   if(regs.h.al != 0x4f || regs.h.ah != 0)
      return -1;

   return regs.x.bx;
}


int VIDEO_VESA::FindMode(int width, int height, int bpp)
{
   int i;
   UDWORD total_error = 65535;
   int mode = 0;

   for(i=0; i<mode_list_length; i++)
   {
      UDWORD error = abs(width - mode_list[i].width) +
         abs(height - mode_list[i].height) +
         abs(bpp - mode_list[i].bpp);

      if(error <= total_error)
      {
         total_error = error;
         mode = i;
      }
   }
   return mode_list[mode].mode_number;
}


int VIDEO_VESA:: SetMode(int mode)
{
   VESA_MODE_INFO_BLOCK vmib;
   __dpmi_regs regs;

   /* set video mode */
   regs.d.eax = VESA_SET_MODE;
   regs.x.bx = mode;
   __dpmi_int(VIDEO_INT_NUM, &regs);

   if(regs.h.al != 0x4f || regs.h.ah != 0)
      return VESA_FAIL;

   GetModeInfo(mode, &vmib);
   
   DWORD LfbSize = LfbSize = vmib.XResolution * vmib.YResolution
      * vmib.BitsPerPixel / 8;
   DWORD len = (LfbSize + 0xfff) & 0xfffff000;
   
   if(addr != 0) free(addr);
   addr = (BYTE*)malloc(len + 0xfff);
   virt_addr = (BYTE*)((DWORD)(addr + 0xfff) & 0xfffff000);
   if(addr == 0)
   {
      printf("Error allocate memory for video!\n");
      exit(10);
   }

   if(__djgpp_map_physical_memory(virt_addr, len,
      vmib.PhysBasePtr) == -1)
   {
      printf("Failed map physical memory for video\n");
      exit(10);
   }

   return VESA_PASS;
}


int VIDEO_VESA::SetMode(int width, int height, int bpp)
{
   int mode = FindMode(width, height, bpp);

   if(SetMode(mode) == VESA_FAIL)
      return VESA_FAIL;

   return VESA_PASS;
}

DWORD VIDEO_VESA::GetVideoBuffer(void)
{
	return (DWORD)virt_addr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -