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

📄 lsys1.cpp

📁 ldraw_DOS游戏开发包
💻 CPP
字号:
//////////////////////////////////////////////////////////////////////////
#include <lsys.h>
#include <dos.h>
#include <stdio.h>
#include <mem.h>
#include <malloc.h>
#include <conio.h>
#include <time.h>
//////////////////////////////////////////////////////////////////////////
char         *VideoBuf=(char *)0xa0000L,     // Video Mem addr in graph mode
             *VideoTextBuf=(char *)0xb8000L, // Video Mem addr in text mode
             *DrawBuf;                       // Active Graph Mem addr 

extern struct TGModeTable GModeTable[SVGA_MAX_MODE]=
{ { 0x03, SVGA_TYPE_TEXT, 80, 25  }, // Text             mode
  { 0x13, SVGA_TYPE_256, 320, 200 }, // 320 * 200 *256   mode
  { 0x5d, SVGA_TYPE_256, 640, 480 }, 
  { 0x5e, SVGA_TYPE_256, 800, 600 }, 
  { 0x101,SVGA_TYPE_256, 640, 480 },
  { 0x103,SVGA_TYPE_256, 800, 600 },
  { 0x1f9,SVGA_TYPE_256, 320, 200 },
  { 0x1f8,SVGA_TYPE_256, 320, 240 },
  { 0x1f3,SVGA_TYPE_256, 512, 384 },
  { 0x00, SVGA_TYPE_X  , 320, 240 },
  { 0x00, SVGA_TYPE_X  , 400, 300 },
  { 0,0,0,0 }, { 0,0,0,0 }, { 0,0,0,0 }, // NULL 
};
struct TGModeTable GModeData={ 0, 0, 0, 0 };
int   LineBase[2000], *DrawLb=LineBase; 
char  lsys_message[200]="NO ERROR";
short DrawLen, DrawWid;
short VGApage=0;
 
////////////////////////////////////////////////////////////////////////////
short lCreateSurface(short len,short wid,LSURFACE *sface,char *shadow,int mode)
{ long size=wid, y; size*=len; int *index;
  
  switch (mode)
  { case LSM_SCREEN: sface->memory=VideoBuf; break;
    case LSM_MEMORY: sface->memory=new char[size]; break;
    case LSM_SHADOW: sface->memory=shadow; break;
    default: sface->memory=NULL; mode=LSM_MEMORY; break;
  }
  sface->mode=0;
  if (mode==LSM_MEMORY&&sface->memory==NULL) {
     sprintf(lsys_message,"error alloc memory for surface bitmap");
     return FALSE; 
  }
  if (mode==LSM_SCREEN&&(len!=GModeData.LEN||wid!=GModeData.WID)) {
     sprintf(lsys_message,"error screen size");
     return FALSE;
  }
  sface->len=len; sface->wid=wid;

  index=new int[wid];
  if (!index) { 
     lDeleteSurface(sface); 
     sprintf(lsys_message,"error make line indexs");
     return FALSE; 
  }
  for (y=0;y<wid;y++) index[y]=y*len;
  sface->index=index; sface->mode=mode; 
  if (mode==LSM_MEMORY) memset(sface->memory,0,size);
  sprintf(lsys_message,"created a %dx%d surface in %lxh",len,wid,sface);
  return TRUE;
}
void  lDeleteSurface(LSURFACE *sface)
{ if (sface->mode==0) return;
  if (DrawBuf==sface->memory) lActiveSurface(NULL);
  if (sface->memory&&sface->mode==LSM_MEMORY) delete sface->memory;
  if (sface->index!=LineBase) delete sface->index;
  sface->mode=0;
}
void  lActiveSurface(LSURFACE *SFACE)
{ if (SFACE==NULL||SFACE->mode==LSM_SCREEN) // to screen
   { DrawLen=GModeData.LEN; DrawWid=GModeData.WID;
     DrawBuf=VideoBuf; DrawLb=LineBase; 
     return;
   }
  if (SFACE->mode==NULL) return;
  DrawBuf=SFACE->memory; 
  DrawLb =SFACE->index;
  DrawLen=SFACE->len; 
  DrawWid=SFACE->wid;
  return;
}
////////////////////////////////////////////////////////////////////////////
extern "C" void cdecl LVGApageX(short page);
extern "C" void cdecl LMemCpy2X(void *dest,void *source,unsigned long len);
static char lEnterModeX(short len,short wid);
////////////////////////////////////////////////////////////////////////////
short lInitGraph(short index)
{ int vgaMode, len, wid, vtype, ret = TRUE;
  int i,j;

  vgaMode=GModeTable[index].VGAMODE; // Load Data
  vtype=GModeTable[index].GMTYPE;
  len=GModeTable[index].LEN;
  wid=GModeTable[index].WID;

  if (vtype==SVGA_TYPE_X) ret = lEnterModeX(len,wid);
    else ret = lEnterGraph(GModeTable[index].VGAMODE);
  if (ret==FALSE) return FALSE;
  
  GModeData.VGAMODE=vgaMode,     // copy data
  GModeData.GMTYPE =vtype, 
  GModeData.LEN   =DrawLen=len, 
  GModeData.WID   =DrawWid=wid;
  DrawLb=LineBase; DrawBuf=VideoBuf;
  for (j=0;j<wid;j++) LineBase[j] = j * len;
  return TRUE;  
}
void  lCloseGraph()
{ lEnterGraph(GModeTable[SVGA_TEXT].VGAMODE);
  GModeData.VGAMODE=0;
}
short lEnterGraph(short mode)
{ short i=TRUE, j;
  union REGS r;
  if (mode<0x100)
   { r.w.ax=mode;
     int386(0x10,&r,&r);
     r.h.ah=0xf;
     int386(0x10,&r,&r);
     if (r.h.al!=mode) i=FALSE;
   }
  else
   { r.w.ax=0x4f02;
     r.w.bx=mode;
     int386(0x10,&r,&r);
     if (r.w.ax!=0x004f) i=FALSE;
   }
  return (i);
}
///// MODE X //////////////////////////////////
struct LVGA_REGISTER
{
   unsigned short port;
   unsigned char index;
   unsigned char value;
};
static LVGA_REGISTER lin_mode_320x240[] =
{
   { 0x3C2, 0x0,  0xE3 },  { 0x3D4, 0x0,  0x5F },  { 0x3D4, 0x1,  0x4F },
   { 0x3D4, 0x2,  0x50 },  { 0x3D4, 0x3,  0x82 },  { 0x3D4, 0x4,  0x54 },
   { 0x3D4, 0x5,  0x80 },  { 0x3D4, 0x6,  0xD  },  { 0x3D4, 0x7,  0x3E },
   { 0x3D4, 0x8,  0x0  },  { 0x3D4, 0x9,  0x41 },  { 0x3D4, 0x10, 0xEA },
   { 0x3D4, 0x11, 0xAC },  { 0x3D4, 0x12, 0xDF },  { 0x3D4, 0x14, 0x0  }, 
   { 0x3D4, 0x15, 0xE7 },  { 0x3D4, 0x16, 0x6  },  { 0x3D4, 0x17, 0xE3 }, 
   { 0x3C4, 0x1,  0x1  },  { 0x3CE, 0x5,  0x40 },  { 0x3CE, 0x6,  0x5  }, 
   { 0x3C0, 0x10, 0x41 },  { 0,     0,    0    } 
};
static LVGA_REGISTER lin_mode_notweak[] =
{
   { 0,     0,    0    }
};
struct LTWEAKED_MODE
{
   int len, wid;
   LVGA_REGISTER *regs;
   int parent;
   int hrs;
   int shift;
   int repeat;
};
static LTWEAKED_MODE lin_xmodes[] =
{
   {  320,  240,  lin_mode_320x240,  0x13, 0, 0, 0  },
   {  400,  300,  lin_mode_notweak,  0x6A, 1, 1, 1  },
   {  0,    0,    NULL,                 0, 0, 0, 0  }
};
static char lEnterModeX(short len,short wid)
{  long c;
   LVGA_REGISTER *reg;
   LTWEAKED_MODE *mode = lin_xmodes;

   for (;(mode->len!=len || mode->wid!=wid);mode++)
     if (!mode->regs) {
         sprintf(lsys_message,"Can not init %dx%d in Mode X",len,wid);
         return FALSE;
     }  
   if (!lEnterGraph(mode->parent)) {
      sprintf(lsys_message,"Can not init the parent mode in Mode X");
      return FALSE;
   }

   outpw(0x3C4, 0x0100);                     /* synchronous reset */
   outp(0x3D4, 0x11);                        /* enable crtc regs 0-7 */
   outp(0x3D5, inp(0x3D5) & 0x7F);
   outpw(0x3C4, 0x0604);                     /* disable chain-4 */
   
   for (reg=mode->regs; reg->port; reg++) {     /* set the VGA registers */
      if (reg->port == 0x3C0) {
	 inp(0x3DA);
	 outp(0x3C0, reg->index | 0x20);
	 outp(0x3C0, reg->value);
      }  else if (reg->port == 0x3C2) {
       	   outp(reg->port, reg->value);
      }  else {
	 outp(reg->port, reg->index); 
	 outp(reg->port+1, reg->value);
      }
   }

   if (mode->hrs) {
      outp(0x3D4, 0x11);  outp(0x3D5, inp(0x3D5)&0x7F);
      outp(0x3D4, 0x04);  outp(0x3D5, inp(0x3D5)+mode->hrs);
      outp(0x3D4, 0x11);  outp(0x3D5, inp(0x3D5)|0x80);
   }
   if (mode->shift) {
      outp(0x3CE, 0x05);  outp(0x3CF,(inp(0x3CF)&0x60)|0x40);
      inp(0x3DA);         outp(0x3C0, 0x30);
      outp(0x3C0, inp(0x3C1)|0x40);
      for (c=0; c<16; c++) {
	 outp(0x3C0, c);
	 outp(0x3C0, c);
      }  outp(0x3C0, 0x20);
   }
   if (mode->repeat) {
      outp(0x3D4, 0x09);
      outp(0x3D5,(inp(0x3D5)&0x60)|mode->repeat);
   }
   outp(0x3D4, 0x13);                       /* set scanline length */
   outp(0x3D5, len/8);
   outpw(0x3C4, 0x0300);                    /* restart sequencer */
   for (c=0;c<0x10000;c++) VideoBuf[c]=0;

   return TRUE;
}

⌨️ 快捷键说明

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