📄 dos_drvr.c
字号:
koutp(0x3cf,0x7c<<(8-(daxpos&7))); readpixel(p+1), drawpixel(p+1,backcol); } } dat = fontptr[(((long)ch)<<3)+zz]; if (charxsiz == 8) { koutp(0x3cf,mask&(dat>>(daxpos&7))); readpixel(p), drawpixel(p,col); koutp(0x3cf,(~mask)&(dat<<(8-(daxpos&7)))); readpixel(p+1), drawpixel(p+1,col); } else { koutp(0x3cf,(0x7c&dat)>>(daxpos&7)); readpixel(p), drawpixel(p,col); koutp(0x3cf,(0x7c&dat)<<(8-(daxpos&7))); readpixel(p+1), drawpixel(p+1,col); } p += 80; //Do not make bytesperline! } } daxpos += charxsiz; } koutp(0x3ce,0x5); koutp(0x3cf,(kinp(0x3cf)&(255-3))+0);}void _nextpage(void){ switch(qsetmode) { case 200: switch(vidoption) { case 1: if (stereomode) { stereonextpage(); if (!origbuffermode) buffermode = transarea = totalarea = 0; } else { visualpage = activepage; setvisualpage(visualpage); if (!origbuffermode) { buffermode = ((transarea<<3) > totalarea); transarea = totalarea = 0; } activepage++; if (activepage >= numpages) activepage = 0; setactivepage(activepage); } break; case 2: copybuf((void *)frameplace,(void *)0xa0000,64000>>2); break; case 6: if (!activepage) redblueblit(screen,&screen[65536],64000L); activepage ^= 1; break; } break; case 350: koutpw(0x3d4,0xc+((pageoffset>>11)<<8)); limitrate(); pageoffset = 225280-pageoffset; //225280 is 352(multiple of 16)*640 break; case 480: koutpw(0x3d4,0xc+((pageoffset>>11)<<8)); limitrate(); pageoffset = 399360-pageoffset; break; }} // _nextpagevoid interrupt stereohandler1(void){ //VR flag if (kinp(0x3c2)&128) { laststereoint = 0; koutpw(0x3d4,((long)(overtbits)<<8)+0x11); koutp(0x3d5,overtbits+16); } if (laststereoint == 1) { visualpage ^= 1; setvisualpage(visualpage|0x80000000); //0x80000000 to ignore qlimitrate } laststereoint++; koutp(0x70,0xc); kinp(0x71); koutp(0xa0,0x20); koutp(0x20,0x20);}void interrupt stereohandler2(void){ //VR flag if (kinp(0x3c2)&128) { laststereoint = 0; koutp(0x378,0xfb+((visualpage&1^1)<<2)); koutpw(0x3d4,((long)overtbits<<8)+0x11); koutp(0x3d5,overtbits+16); } if (laststereoint == 1) { visualpage ^= 1; setvisualpage(visualpage|0x80000000); //0x80000000 to ignore qlimitrate } laststereoint++; koutp(0x70,0xc); kinp(0x71); koutp(0xa0,0x20); koutp(0x20,0x20);}void stereonextpage(void){ koutp(0x70,0xc); kinp(0x71); //koutpw(0x70,0x420b); if ((activepage&1) == 0) { if (stereomode == 1) { clearbuf((void *)(ylookup[ydim-1]+frameplace),xdim>>4,whiteband); clearbuf((void *)(ylookup[ydim-1]+frameplace+(xdim>>2)),(xdim>>2)-(xdim>>4),blackband); } activepage++; setactivepage(activepage); return; } if (stereomode == 1) { clearbuf((void *)(ylookup[ydim-1]+frameplace),(xdim>>2)-(xdim>>4),whiteband); clearbuf((void *)(ylookup[ydim-1]+frameplace+xdim-(xdim>>2)),xdim>>4,blackband); } if (visualpage < (numpages&~1)-2) visualpage += 2; else visualpage &= 1; if (activepage < (numpages&~1)-1) activepage++; else activepage = 0; setactivepage(activepage);}void setstereo(long dastereomode){ //long i, dist, blackdist, whitedist, t1, t2, numlines; //char c1, c2; long i, dist, blackdist, whitedist; if ((vidoption != 1) || (numpages < 2)) return; if (stereomode) //---------------Uninitialize old stereo mode { if ((xdim == 320) && (ydim == 200)) { //back to 70 hz koutp(0x3c2,o3c2); } //Uninit VR flag koutpw(0x3d4,(((long)overtbits+32)<<8)+0x11); //Uninit RTC _disable(); koutp(0xa1,(kinp(0xa1)&~1)|(oa1&1)); koutp(0x70,0xa); koutp(0x71,ortca); koutp(0x70,0xb); koutp(0x71,ortcb); uninstallbistereohandlers(); _enable(); stereomode = 0; ostereopixelwidth = -1; setview(windowx1,windowy1,windowx2,windowy2); if (stereomode == 1) { for(i=0;i<numpages;i++) { setactivepage(i); clearbuf((void *)(ylookup[ydim-1]+frameplace),xdim>>2,blackband); } setactivepage(activepage); } } //------------------------------------- Initialize new stereo mode stereomode = dastereomode; if (!stereomode) return; activepage = (visualpage & ~1)+2; if (activepage >= numpages-1) activepage = 0; if (stereomode == 1) { blackdist = 0x7fffffff; whitedist = 0x80000000; koutp(0x3c7,0); for(i=0;i<256;i++) { dist = (kinp(0x3c9)&255)+(kinp(0x3c9)&255)+(kinp(0x3c9)&255); if (dist < blackdist) { blackdist = dist; blackband = i; } if (dist > whitedist) { whitedist = dist; whiteband = i; } } blackband += (blackband<<8); blackband += (blackband<<16); whiteband += (whiteband<<8); whiteband += (whiteband<<16); } if ((xdim == 320) && (ydim == 200)) { //80 hz o3c2 = kinp(0x3cc); koutp(0x3c2,(o3c2&0xf3)+4); } //Init RTC _disable(); if (stereomode == 1) installbistereohandlers(stereohandler1); if (stereomode == 2) installbistereohandlers(stereohandler2); koutp(0x70,0xa); ortca = kinp(0x71); if (stereomode == 1) koutp(0x71,0x28); //+8 = 256hz if (stereomode == 2) koutp(0x71,0x26); //+6 = 1024hz koutp(0x70,0xb); ortcb = kinp(0x71); koutp(0x71,0x42); koutp(0x70,0xc); kinp(0x71); oa1 = kinp(0xa1); koutp(0xa1,oa1&~1); _enable(); //Init VR flag koutp(0x3d4,0x11); overtbits = kinp(0x3d5) & ~(16+32); koutp(0x3d5,overtbits); koutp(0x3d5,overtbits+16);}#define RTCBUFSIZ 16static unsigned short rtcopmsel, rtcormseg, rtcormoff;static unsigned long rtcopmoff;//Use bicomc.asm as a template if this asm code needs re-writingstatic char rtcrmbuffer[RTCBUFSIZ] ={ 0x50, //push ax 0xb0,0x0c, //mov al, 0ch 0xe6,0x70, //out 70h, al 0xe4,0x71, //in al, 71h 0xb0,0x20, //mov al, 20h 0xe6,0xa0, //out 0a0h, al 0xe6,0x20, //out 20h, al 0x58, //pop ax 0xcf //iret};void *engconvalloc32 (unsigned long size){ union REGS r; r.x.eax = 0x0100; //DPMI allocate DOS memory r.x.ebx = ((size+15)>>4); //Number of paragraphs requested int386(0x31,&r,&r); if (r.x.cflag != 0) //Failed return ((unsigned long)0); return ((void *)((r.x.eax&0xffff)<<4)); //Returns full 32-bit offset}void installbistereohandlers(void far *stereohan){ //char *ptr; union REGS r; struct SREGS sr; void *lowp; //int c; //Get old protected mode handler r.x.eax = 0x3500+0x70; /* DOS get vector (INT 0Ch) */ sr.ds = sr.es = 0; int386x(0x21,&r,&r,&sr); rtcopmsel = (unsigned short)sr.es; rtcopmoff = r.x.ebx; //Get old real mode handler r.x.eax = 0x0200; /* DPMI get real mode vector */ r.h.bl = 0x70; int386(0x31,&r,&r); rtcormseg = (unsigned short)r.x.ecx; rtcormoff = (unsigned short)r.x.edx; //Allocate memory in low memory to store real mode handler if ((lowp = engconvalloc32(RTCBUFSIZ)) == 0) { printf("Couldn't allocate conventional memory.\n"); exit(1); } memcpy(lowp,(void *)rtcrmbuffer,RTCBUFSIZ); //Set new protected mode handler r.x.eax = 0x2500+0x70; /* DOS set vector (INT 0Ch) */ r.x.edx = FP_OFF(stereohan); sr.ds = FP_SEG(stereohan); //DS:EDX == &handler sr.es = 0; int386x(0x21,&r,&r,&sr); //Set new real mode handler (must be after setting protected mode) r.x.eax = 0x0201; r.h.bl = 0x70; //CX:DX == real mode &handler r.x.ecx = ((((long)lowp)>>4)&0xffff); //D32realseg r.x.edx = (((long)lowp)&0xf); //D32realoff int386(0x31,&r,&r);}void uninstallbistereohandlers(void){ union REGS r; struct SREGS sr; //restore old protected mode handler r.x.eax = 0x2500+0x70; /* DOS set vector (INT 0Ch) */ r.x.edx = rtcopmoff; sr.ds = rtcopmsel; /* DS:EDX == &handler */ sr.es = 0; int386x(0x21,&r,&r,&sr); //restore old real mode handler r.x.eax = 0x0201; /* DPMI set real mode vector */ r.h.bl = 0x70; r.x.ecx = (unsigned long)rtcormseg; //CX:DX == real mode &handler r.x.edx = (unsigned long)rtcormoff; int386(0x31,&r,&r);}void inittimer(void){ outp(0x43,0x34); outp(0x40,(1193181/120)&255); outp(0x40,(1193181/120)>>8); oldtimerhandler = _dos_getvect(0x8); _disable(); _dos_setvect(0x8, timerhandler); _enable();}void uninittimer(void){ outp(0x43,0x34); outp(0x40,0); outp(0x40,0); //18.2 times/sec _disable(); _dos_setvect(0x8, oldtimerhandler); _enable();}void initkeys(void){ oldkeyhandler = _dos_getvect(0x9); _disable(); _dos_setvect(0x9, keyhandler); _enable();}void uninitkeys(void){ short *ptr; _dos_setvect(0x9, oldkeyhandler); //Turn off shifts to prevent stucks with quitting ptr = (short *)0x417; *ptr &= ~0x030f;}int _setgamemode(char davidoption, long daxdim, long daydim){ long i, j, ostereomode; if ((qsetmode == 200) && (vidoption == davidoption) && (xdim == daxdim) && (ydim == daydim)) return(0); vidoption = davidoption; xdim = daxdim; ydim = daydim; strcpy(kensmessage,"!!!! BUILD engine&tools programmed by Ken Silverman of E.G. RI. (c) Copyright 1995 Ken Silverman. Summary: BUILD = Ken. !!!!"); if (getkensmessagecrc(FP_OFF(kensmessage)) != 0x56c764d4) { setvmode(0x3); printf("Nice try.\n"); exit(0); } ostereomode = stereomode; if (stereomode) setstereo(0L); activepage = visualpage = 0; switch(vidoption) { case 1: i = xdim*ydim; break; case 2: xdim = 320; ydim = 200; i = xdim*ydim; break; case 6: xdim = 320; ydim = 200; i = 131072; break; default: return(-1); } j = ydim*4*sizeof(long); //Leave room for horizlookup&horizlookup2 if (screen != NULL) { if (screenalloctype == 0) kkfree((void *)screen); if (screenalloctype == 1) suckcache((long *)screen); screen = NULL; } screenalloctype = 0; if ((screen = (char *)kkmalloc(i+(j<<1))) == NULL) { allocache((long *)&screen,i+(j<<1),&permanentlock); screenalloctype = 1; } frameplace = FP_OFF(screen); horizlookup = (long *)(frameplace+i); horizlookup2 = (long *)(frameplace+i+j); horizycent = ((ydim*4)>>1); switch(vidoption) { case 1: //bytesperline is set in this function if (setvesa(xdim,ydim) < 0) return(-1); break; case 2: horizycent = ((ydim*4)>>1); //HACK for switching to this mode case 6: bytesperline = xdim; setvmode(0x13); break; default: return(-1); } //Force drawrooms to call dosetaspect & recalculate stuff oxyaspect = oxdimen = oviewingrange = -1; setvlinebpl(bytesperline); j = 0; for(i=0;i<=ydim;i++) ylookup[i] = j, j += bytesperline; numpages = 1; if (vidoption == 1) numpages = min(maxpages,8); setview(0L,0L,xdim-1,ydim-1); clearallviews(0L); setbrightness(curbrightness, &palette[0]); if (searchx < 0) { searchx = halfxdimen; searchy = (ydimen>>1); } if (ostereomode) setstereo(ostereomode); qsetmode = 200; return(0);}void _platform_init(int argc, char **argv, const char *title, const char *icon){ // no op in DOS, currently. --ryan.}void clear2dscreen(void){ if (qsetmode == 350) fillscreen16(pageoffset>>3,0L,640L*350L); else if (qsetmode == 480) { if (ydim16 <= 336) fillscreen16(pageoffset>>3,0L,640L*336L); else fillscreen16(pageoffset>>3,0L,640L*480L); }}void _idle(void){ // no-op in DOS, which is non-multitasking. However, if someone were to // add Desqview/win95/OS2/etc support, timeslicing would be good.}void *_getVideoBase(void){ return((void *) 0xa0000);}void _updateScreenRect(long x, long y, long w, long h){}int using_opengl(void){ return(0);}// end of dos_driver.c ...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -