// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman // Ken Silverman's official web site: "http://www.advsys.net/ken" // See the included license file "BUILDLIC.TXT" for license info. // This file has been modified from Ken Silverman's original release // (Actually, most of it was moved here from original BUILD source.) #ifndef PLATFORM_DOS #error Please do not compile this if PLATFORM_DOS is not defined. #endif // !!! check these includes against original engine.c !!! #include #include #include #include #include #include "pragmas.h" #include #include #include #include #include "platform.h" #include "display.h" #include "build.h" #include "cache1d.h" #include "ves2.h" #include "engine.h" static unsigned char tempbuf[MAXWALLS]; extern long transarea; extern long totalarea; extern long beforedrawrooms; extern long stereowidth, stereopixelwidth, ostereopixelwidth; extern volatile long stereomode, visualpage, activepage, whiteband, blackband; extern volatile char oa1, o3c2, ortca, ortcb, overtbits, laststereoint; extern char pow2char[8]; extern long pow2long[32]; extern char kensmessage[128]; static short capturecount = 0; static char screenalloctype = 255; static char pcxheader[128] = { 0xa,0x5,0x1,0x8,0x0,0x0,0x0,0x0,0x3f,0x1,0xc7,0x0, 0x40,0x1,0xc8,0x0,0x0,0x0,0x0,0x8,0x8,0x8,0x10,0x10, 0x10,0x18,0x18,0x18,0x20,0x20,0x20,0x28,0x28,0x28,0x30,0x30, 0x30,0x38,0x38,0x38,0x40,0x40,0x40,0x48,0x48,0x48,0x50,0x50, 0x50,0x58,0x58,0x58,0x60,0x60,0x60,0x68,0x68,0x68,0x70,0x70, 0x70,0x78,0x78,0x78,0x0,0x1,0x40,0x1,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, }; static char vgapal16[48] = { 00,00,00,00,00,42,00,42,00,00,42,42,42,00,00,42,00,42,42,21,00,42,42,42, 21,21,21,21,21,63,21,63,21,21,63,63,63,21,21,63,21,63,63,63,21,63,63,63, }; static void (__interrupt __far *oldtimerhandler)(void); static void (__interrupt __far *oldkeyhandler)(void); extern long setvlinebpl(long); #pragma aux setvlinebpl parm [eax]; void *kkmalloc(size_t size); #pragma aux kkmalloc =\ "call kmalloc",\ parm [eax]\ void kkfree(void *buffer); #pragma aux kkfree =\ "call kfree",\ parm [eax]\ unsigned char _readlastkeyhit(void) { return(kinp(0x60)); } // _readlastkeyhit void _uninitengine(void) { long i; if (vidoption == 1) uninitvesa(); if (stereomode) setstereo(0L); if (screen != NULL) { if (screenalloctype == 0) kkfree((void *)screen); //if (screenalloctype == 1) suckcache(screen); //Cache already gone screen = NULL; } for(i=0;i= 640*336)) p -= 640*336; else p += pageoffset; p >>= 3; koutp(0x3ce,0x4); koutp(0x3cf,0); dat = ((readpixel(p+0xa0000)&mask)>0); koutp(0x3cf,1); dat += (((readpixel(p+0xa0000)&mask)>0)<<1); koutp(0x3cf,2); dat += (((readpixel(p+0xa0000)&mask)>0)<<2); koutp(0x3cf,3); dat += (((readpixel(p+0xa0000)&mask)>0)<<3); return(dat); } int screencapture(char *filename, char inverseit) { char *ptr; long fil, i, bufplc, p, col, ncol, leng, numbytes, xres; filename[4] = ((capturecount/1000)%10)+48; filename[5] = ((capturecount/100)%10)+48; filename[6] = ((capturecount/10)%10)+48; filename[7] = (capturecount%10)+48; if ((fil=open(filename,O_BINARY|O_CREAT|O_TRUNC|O_WRONLY,S_IWRITE))==-1) return(-1); if (qsetmode == 200) { pcxheader[8] = ((xdim-1)&255); pcxheader[9] = (((xdim-1)>>8)&255); pcxheader[10] = ((ydim-1)&255); pcxheader[11] = (((ydim-1)>>8)&255); pcxheader[12] = (xdim&255); pcxheader[13] = ((xdim>>8)&255); pcxheader[14] = (ydim&255); pcxheader[15] = ((ydim>>8)&255); pcxheader[66] = (xdim&255); pcxheader[67] = ((xdim>>8)&255); } else { pcxheader[8] = ((640-1)&255); pcxheader[9] = (((640-1)>>8)&255); pcxheader[10] = ((qsetmode-1)&255); pcxheader[11] = (((qsetmode-1)>>8)&255); pcxheader[12] = (640&255); pcxheader[13] = ((640>>8)&255); pcxheader[14] = (qsetmode&255); pcxheader[15] = ((qsetmode>>8)&255); pcxheader[66] = (640&255); pcxheader[67] = ((640>>8)&255); } write(fil,&pcxheader[0],128); if (qsetmode == 200) { ptr = (char *)frameplace; numbytes = xdim*ydim; xres = xdim; } else { numbytes = (mul5(qsetmode)<<7); xres = 640; } bufplc = 0; p = 0; while (p < numbytes) { koutp(97,kinp(97)|3); if (qsetmode == 200) { col = *ptr; p++; ptr++; } else { col = readpixel16(p); p++; if ((inverseit == 1) && (((col&7) == 0) || ((col&7) == 7))) col ^= 15; } leng = 1; if (qsetmode == 200) ncol = *ptr; else { ncol = readpixel16(p); if ((inverseit == 1) && (((ncol&7) == 0) || ((ncol&7) == 7))) ncol ^= 15; } while ((ncol == col) && (p < numbytes) && (leng < 63) && ((p%xres) != 0)) { leng++; if (qsetmode == 200) { p++; ptr++; ncol = *ptr; } else { p++; ncol = readpixel16(p); if ((inverseit == 1) && (((ncol&7) == 0) || ((ncol&7) == 7))) ncol ^= 15; } } koutp(97,kinp(97)&252); if ((leng > 1) || (col >= 0xc0)) { tempbuf[bufplc++] = (leng|0xc0); if (bufplc == 4096) { bufplc = 0; if (write(fil,&tempbuf[0],4096) < 4096) { close(fil); return(-1); } } } tempbuf[bufplc++] = col; if (bufplc == 4096) { bufplc = 0; if (write(fil,&tempbuf[0],4096) < 4096) { close(fil); return(-1); } } } tempbuf[bufplc++] = 0xc; if (bufplc == 4096) { bufplc = 0; if (write(fil,&tempbuf[0],4096) < 4096) { close(fil); return(-1); } } if (qsetmode == 200) { VBE_getPalette(0,256,&tempbuf[4096]); for(i=0;i<256;i++) { tempbuf[bufplc++] = (tempbuf[(i<<2)+4096+2]<<2); if (bufplc == 4096) { bufplc = 0; if (write(fil,&tempbuf[0],4096) < 4096) { close(fil); return(-1); } } tempbuf[bufplc++] = (tempbuf[(i<<2)+4096+1]<<2); if (bufplc == 4096) { bufplc = 0; if (write(fil,&tempbuf[0],4096) < 4096) { close(fil); return(-1); } } tempbuf[bufplc++] = (tempbuf[(i<<2)+4096+0]<<2); if (bufplc == 4096) { bufplc = 0; if (write(fil,&tempbuf[0],4096) < 4096) { close(fil); return(-1); } } } } else { for(i=0;i<768;i++) { if (i < 48) tempbuf[bufplc++] = (vgapal16[i]<<2); else tempbuf[bufplc++] = 0; if (bufplc == 4096) { bufplc = 0; if (write(fil,&tempbuf[0],4096) < 4096) { close(fil); return(-1); } } } } if (bufplc > 0) if (write(fil,&tempbuf[0],bufplc) < bufplc) { close(fil); return(-1); } close(fil); capturecount++; return(0); } void printscreeninterrupt(void) { int5(); } void drawline16(long x1, long y1, long x2, long y2, char col) { long i, dx, dy, p, pinc, d; char lmask, rmask; dx = x2-x1; dy = y2-y1; if (dx >= 0) { if ((x1 > 639) || (x2 < 0)) return; if (x1 < 0) { if (dy) y1 += scale(0-x1,dy,dx); x1 = 0; } if (x2 > 639) { if (dy) y2 += scale(639-x2,dy,dx); x2 = 639; } } else { if ((x2 > 639) || (x1 < 0)) return; if (x2 < 0) { if (dy) y2 += scale(0-x2,dy,dx); x2 = 0; } if (x1 > 639) { if (dy) y1 += scale(639-x1,dy,dx); x1 = 639; } } if (dy >= 0) { if ((y1 >= ydim16) || (y2 < 0)) return; if (y1 < 0) { if (dx) x1 += scale(0-y1,dx,dy); y1 = 0; } if (y2 >= ydim16) { if (dx) x2 += scale(ydim16-1-y2,dx,dy); y2 = ydim16-1; } } else { if ((y2 >= ydim16) || (y1 < 0)) return; if (y2 < 0) { if (dx) x2 += scale(0-y2,dx,dy); y2 = 0; } if (y1 >= ydim16) { if (dx) x1 += scale(ydim16-1-y1,dx,dy); y1 = ydim16-1; } } setcolor16((long)col); if (x1 == x2) { if (y2 < y1) i = y1, y1 = y2, y2 = i; koutpw(0x3ce,0x8+(256<<((x1&7)^7))); //bit mask vlin16((((mul5(y1)<<7)+x1+pageoffset)>>3)+0xa0000,y2-y1+1); return; } if (y1 == y2) { if (x2 < x1) i = x1, x1 = x2, x2 = i; lmask = (0x00ff>>(x1&7)); rmask = (0xff80>>(x2&7)); p = (((mul5(y1)<<7)+x1+pageoffset)>>3)+0xa0000; dx = (x2>>3)-(x1>>3); if (dx == 0) { koutpw(0x3ce,0x8+((lmask&rmask)<<8)); drawpixel(p,readpixel(p)); return; } dx--; koutpw(0x3ce,0x8+(lmask<<8)); drawpixel(p,readpixel(p)); p++; if (dx > 0) { koutp(0x3cf,0xff); clearbufbyte((void *)p,dx,0L); p += dx; } koutp(0x3cf,rmask); drawpixel(p,readpixel(p)); return; } dx = klabs(x2-x1)+1; dy = klabs(y2-y1)+1; if (dx >= dy) { if (x2 < x1) { i = x1; x1 = x2; x2 = i; i = y1; y1 = y2; y2 = i; } p = (mul5(y1)<<7)+x1+pageoffset; d = 0; if (y2 > y1) pinc = 640; else pinc = -640; for(i=dx;i>0;i--) { drawpixel16(p); d += dy; if (d >= dx) { d -= dx; p += pinc; } p++; } return; } if (y2 < y1) { i = x1; x1 = x2; x2 = i; i = y1; y1 = y2; y2 = i; } p = (mul5(y1)<<7)+x1+pageoffset; d = 0; if (x2 > x1) pinc = 1; else pinc = -1; for(i=dy;i>0;i--) { drawpixel16(p); d += dx; if (d >= dy) { d -= dy; p += pinc; } p += 640; } } void qsetmode640350(void) { if (qsetmode != 350) { stereomode = 0; setvmode(0x10); pageoffset = 0; ydim16 = 350; koutpw(0x3d4,0xc+((pageoffset>>11)<<8)); koutpw(0x3ce,0x0f00); //set/reset koutpw(0x3ce,0x0f01); //enable set/reset fillscreen16(0L,0L,640L*350L); } qsetmode = 350; } void qsetmode640480(void) { short i; if (qsetmode != 480) { stereomode = 0; setvmode(0x12); i = 479-144; koutpw(0x3d4,0x18+((i&255)<<8)); //line compare koutp(0x3d4,0x7); koutp(0x3d5,(kinp(0x3d5)&239)|((i&256)>>4)); koutp(0x3d4,0x9); koutp(0x3d5,(kinp(0x3d5)&191)|((i&512)>>3)); pageoffset = 92160; koutpw(0x3d4,0xc+((pageoffset>>11)<<8)); koutpw(0x3ce,0x0f00); //set/reset koutpw(0x3ce,0x0f01); //enable set/reset fillscreen16(0L,8L,640L*144L); fillscreen16((640L*144L)>>3,0L,640L*336L); pageoffset = 92160; ydim16 = 336; } qsetmode = 480; } void printext16(long xpos, long ypos, short col, short backcol, char name[82], char fontsize) { long p, z, zz, charxsiz, daxpos; char ch, dat, mask, *fontptr; daxpos = xpos; koutp(0x3ce,0x5); koutp(0x3cf,(kinp(0x3cf)&(255-3))+2); koutp(0x3ce,0x8); if (fontsize == 1) { fontptr = smalltextfont; charxsiz = 4; } else { fontptr = textfont; charxsiz = 8; } z = 0; while (name[z] != 0) { ch = name[z]; z++; mask = pow2char[8-(daxpos&7)]-1; p = ypos*80 + (daxpos>>3)+0xa0000; //Do not make ylookup! if ((daxpos&7) == 0) { for(zz=0;zz<8;zz++) { if (backcol >= 0) { koutp(0x3cf,0xff); if (charxsiz == 4) koutp(0x3cf,0x7c); readpixel(p), drawpixel(p,(long)backcol); } koutp(0x3cf,fontptr[(((long)ch)<<3)+zz]); if (charxsiz == 4) koutp(0x3cf,0x7c&fontptr[(((long)ch)<<3)+zz]); readpixel(p), drawpixel(p,col); p += 80; } } else { for(zz=0;zz<8;zz++) { if (backcol >= 0) { if (charxsiz == 8) { koutp(0x3cf,mask); readpixel(p), drawpixel(p,backcol); koutp(0x3cf,~mask); readpixel(p+1), drawpixel(p+1,backcol); } else { koutp(0x3cf,0x7c>>(daxpos&7)); readpixel(p), drawpixel(p,backcol); 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; } } // _nextpage void 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>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 16 static unsigned short rtcopmsel, rtcormseg, rtcormoff; static unsigned long rtcopmoff; //Use bicomc.asm as a template if this asm code needs re-writing static 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 ...