#include "ted5.h" #pragma hdrstop extern char far TEDCHAR,far VGAPAL; void Quit(char *string); void drawchar(int x,int y,int chr); void centerwindow (int width, int height); int win_xl,win_yl,win_xh,win_yh; int screencenterx = 19,screencentery = 11; unsigned char keydown[256]; unsigned leftedge,yshift,xormask,MouseStatus,sx,sy; void interrupt (*oldint9) ()=NULL; enum {false,true} boolean; memptr CGAfont,VGAfont; unsigned doubled[256]; // // Special vars to handle EGA3 mouse mode // int EGA3mx,EGA3my; //////////////////////////////////////////////////////////////////// // // Return a file's length // //////////////////////////////////////////////////////////////////// long filelen(char *filename) { long size; int handle; if ((handle=open(filename,O_BINARY))==-1) return 0; size=filelength(handle); close(handle); return size; } //////////////////////////////////////////////////////////////////// // // WaitVBL // //////////////////////////////////////////////////////////////////// void WaitVBL(int times) { asm mov cx,times asm mov dx,crtcaddr asm add dx,6 waitvbl1: asm in al,dx asm test al,00001000b //;look for vbl asm jnz waitvbl1 waitvbl2: asm in al,dx asm test al,00001000b //;look for vbl asm jz waitvbl2 asm loop waitvbl1 } //////////////////////////////////////////////////////////////////// // // Int9ISR // Called for every keypress. Keeps track of which keys are down, and passes // the key on to DOS after clearing the dos buffer (max 1 char in buffer). // //////////////////////////////////////////////////////////////////// void interrupt Int9ISR () { int key = inportb (0x60); /* get the key pressed */ if (key>127) keydown [key-128] = false; /* break scan code */ else { keydown [key] = true; /* make scan code */ poke (0x40,0x1c,peek(0x40,0x1a)); /* clear the bios key buffer */ } asm { push ax push bx push cx push dx push si push di push bp } oldint9 (); /* give it to DOS */ asm { pop bp pop di pop si pop dx pop cx pop bx pop ax } outport (0x20,0x20); /* tell the int manager we got it */ } //////////////////////////////////////////////////////////////////// // // SetupKBD // Clears the keydown array and installs the INT 9 ISR if it isn't already // hooked up. // //////////////////////////////////////////////////////////////////// void SetupKBD () { void far *vect = getvect (9); int i; for (i=0;i<128;i++) /* clear our key down table */ keydown[i]= false; poke (0x40,0x1c,peek(0x40,0x1a)); /* clear the bios key buffer */ if ( &Int9ISR != vect ) /* is our handler allready set up? */ { oldint9 = vect; setvect (9,Int9ISR); } } //////////////////////////////////////////////////////////////////// // // ShutdownKBD // Sets the int 9 vector back to oldint 9 // //////////////////////////////////////////////////////////////////// void ShutdownKBD () { if (oldint9 != NULL) setvect (9,oldint9); } //////////////////////////////////////////////////////////////////// // // clearkeys // Clears out the bios buffer and zeros out the keydown array // //////////////////////////////////////////////////////////////////// void clearkeys (void) { int i; while (bioskey (1)) bioskey(0); for (i=0;i<128;i++) keydown [i]=0; } //////////////////////////////////////////////////////////////////// // // Mouse Routines // //////////////////////////////////////////////////////////////////// int MouseInit(void) { union REGS regs; unsigned char far *vector; if ((vector=MK_FP(peek(0,0x33*4+2),peek(0,0x33*4)))==NULL) return 0; if (*vector == 207) return MouseStatus = 0; _AX=0; geninterrupt(0x33); EGA3mx=800/2; EGA3my=600/2; // // Set CGA mouse cursor (normal one sucks) // if (videomode==CGA) { static unsigned CGAcursor[]= { 0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x000f,0x0c03,0x3c03, 0xff03,0xffff,0xffff,0xffff,0xffff,0xffff, 0xf000,0xcc00,0xc300,0xc0c0,0xc030,0xc00c,0xc03f,0xcc30,0xf30c,0xc30c, 0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000 }; _BX=0; _CX=0; _DX=FP_OFF(CGAcursor); _ES=_DS; _AX=9; geninterrupt(0x33); } return MouseStatus = 1; } void MouseOrigin(int x,int y) { if (!MouseStatus) return; _CX=x; _DX=y; _AX=4; geninterrupt(0x33); } void MouseLimits(int xmin,int xmax,int ymin,int ymax) { if (!MouseStatus) return; _CX=xmin; _DX=xmax; _AX=7; geninterrupt(0x33); _CX=ymin; _DX=ymax; _AX=8; geninterrupt(0x33); } void MouseHide(void) { if (!MouseStatus) return; _AX=2; geninterrupt(0x33); } void MouseShow(void) { if (!MouseStatus) return; _AX=1; geninterrupt(0x33); } int MouseButton(void) { union REGS regs; if (!MouseStatus) return 0; regs.x.ax=3; int86(0x33,®s,®s); return(regs.x.bx); } void MouseCoords(int *x,int *y) { union REGS regs; if (!MouseStatus) return; regs.x.ax=3; int86(0x33,®s,®s); *x=regs.x.cx; *y=regs.x.dx; *x/=2; if (videomode==EGA2) *x*=2; } ///////////////////////// // // print // Prints a string at sx,sy. No clipping!!! // ///////////////////////// void print (const char *str) { char ch; while ((ch=*str++) != 0) if (ch == '\n') { sy++; sx=leftedge; } else if (ch == '\r') sx=leftedge; else drawchar (sx++,sy,ch); } void fprint (const char huge *str) { char ch; while ((ch=*str++) != 0) if (ch == '\n') { sy++; sx=leftedge; } else if (ch == '\r') sx=leftedge; else drawchar (sx++,sy,ch); } //////////////////////////////////////////////////////////////////// // // print hex byte // //////////////////////////////////////////////////////////////////// void printhexb(unsigned char value) { int loop; char hexstr[16]="0123456789ABCDEF",str[2]=""; for (loop=0;loop<2;loop++) { str[0]=hexstr[(value>>(1-loop)*4)&15]; print(str); } } //////////////////////////////////////////////////////////////////// // // print hex // //////////////////////////////////////////////////////////////////// void printhex(unsigned value) { print("$"); printhexb(value>>8); printhexb(value&0xff); } //////////////////////////////////////////////////////////////////// // // print int // //////////////////////////////////////////////////////////////////// void printint(unsigned value) { char temp[10]; ultoa((unsigned long)value,temp,10); print(temp); } //////////////////////////////////////////////////////////////////// // // print bin // //////////////////////////////////////////////////////////////////// void printbin(unsigned value) { int loop; print("%"); for (loop=0;loop<16;loop++) if ((value>>15-loop)&1) print("1"); else print("0"); } //////////////////////////////////////////////////////////////////// // // input unsigned // //////////////////////////////////////////////////////////////////// unsigned inputint(int numchars) { char string[18]="",digit,hexstr[16]="0123456789ABCDEF"; unsigned value,loop,loop1; if (!input(string,numchars)) return ESCOUT; if (string[0]=='$') { int digits; digits=strlen(string)-2; if (digits<0) return 0; for (value=0,loop1=0;loop1<=digits;loop1++) { digit=toupper(string[loop1+1]); for (loop=0;loop<16;loop++) if (digit==hexstr[loop]) { value|=(loop<<(digits-loop1)*4); break; } } } else if (string[0]=='%') { int digits; digits=strlen(string)-2; if (digits<0) return 0; for (value=0,loop1=0;loop1<=digits;loop1++) { if (string[loop1+1]<'0' || string[loop1+1]>'1') return 0; value|=(string[loop1+1]-'0')<<(digits-loop1); } } else value=atoi(string); return value; } //////////////////////////////////////////////////////////////////// // // line input routine // //////////////////////////////////////////////////////////////////// int input(char *string,int max) { char key; int count=0,loop; do { key=get()&0xff; if ((key==127 || key==8)&&count>0) { count--; drawchar(sx,sy,' '); sx--; } if (key>=' ' && key<='z' && count>(7-k))&1]; } // // Now, change video modes! // switch(vid) { case TEXT: _AX=3; break; case CGA: screencenterx=19; screencentery=11; scrnbot=199; scrnrgt=319; _AX=4; break; case EGA1: screencenterx=19; screencentery=11; scrnbot=199; scrnrgt=319; _AX=0x0d; break; case EGA2: screencenterx=39; screencentery=29; scrnbot=479; scrnrgt=638; _AX=0x12; break; case VGA: _AX=0x13; screencenterx=19; screencentery=11; scrnbot=199; scrnrgt=319; } geninterrupt(0x10); videomode=vid; // // Set CGA mouse cursor (normal one sucks) // if (vid==CGA) { static unsigned CGAcursor[]= { 0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x000f,0x0c03,0x3c03, 0xff03,0xffff,0xffff,0xffff,0xffff,0xffff, 0xf000,0xcc00,0xc300,0xc0c0,0xc030,0xc00c,0xc03f,0xcc30,0xf30c,0xc30c, 0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000 }; _BX=0; _CX=0; _DX=FP_OFF(CGAcursor); _ES=_DS; _AX=9; geninterrupt(0x33); } else // // Move EGA font into LATCH memory! // if (vid==EGA1 || vid==EGA2) { unsigned i,s=FP_SEG(&TEDCHAR),o=FP_OFF(&TEDCHAR); outport(GCindex,GCmode); for (i=0;i<4;i++) { outport(SCindex,SCmapmask | (1< 2) expwinh (width-2,height); WaitVBL (1); centerwindow (width,height); } void expwinv (int width, int height) { if (height >2) expwinv (width,height-2); WaitVBL (1); centerwindow (width,height); } void expwin (int width, int height) { if (width > 2) { if (height >2) expwin (width-2,height-2); else expwinh (width-2,height); } else if (height >2) expwinv (width,height-2); WaitVBL (1); centerwindow (width,height); } //////////////////////////////////////////////////////////// // // Save a *LARGE* file from a FAR buffer! // by John Romero (C) 1990 Gamer's Edge // //////////////////////////////////////////////////////////// void SaveFile(char *filename,char huge *buffer,long offset,long size) { unsigned int handle,buf1,buf2,offlo,offhi,sizelo,sizehi; buf1=FP_OFF(buffer); buf2=FP_SEG(buffer); offlo=offset&0xffff; offhi=offset>>16; sizelo=size&0xffff; sizehi=size>>16; asm mov ax,offlo asm or ax,offhi asm jz CREATEIT asm mov dx,filename asm mov ax,3d02h // OPEN w/handle (read only) asm int 21h asm jnc L0 return; L0: asm mov handle,ax asm mov bx,handle asm mov dx,offlo asm mov cx,offhi asm mov ax,4200h asm int 21h // SEEK (to file offset) asm jc out asm jmp DOSAVE CREATEIT: asm mov dx,filename asm mov ax,3c00h // CREATE w/handle (read only) asm xor cx,cx asm int 21h asm jc out asm mov handle,ax DOSAVE: asm cmp WORD PTR sizehi,0 // larger than 1 segment? asm je L2 L1: asm push ds asm mov bx,handle asm mov cx,8000h asm mov dx,buf1 asm mov ax,buf2 asm mov ds,ax asm mov ah,40h // WRITE w/handle asm int 21h asm pop ds asm add WORD PTR buf2,800h // bump ptr up 1/2 segment asm sub WORD PTR sizelo,8000h // done yet? asm sbb WORD PTR sizehi,0 asm cmp WORD PTR sizehi,0 asm ja L1 asm cmp WORD PTR sizelo,8000h asm jae L1 L2: asm push ds asm mov bx,handle asm mov cx,sizelo asm mov dx,buf1 asm mov ax,buf2 asm mov ds,ax asm mov ah,40h // WRITE w/handle asm int 21h asm pop ds out: asm mov bx,handle // CLOSE w/handle asm mov ah,3eh asm int 21h } //////////////////////////////////////////////////////////// // // Load a *LARGE* file into a FAR buffer! // by John Romero (C) 1990 Gamer's Edge // //////////////////////////////////////////////////////////// unsigned long LoadFile(char *filename,char huge *buffer,long offset,long size) { unsigned handle,flength1=0,flength2=0,buf1,buf2,len1,len2, rsize1,rsize2,roffset1,roffset2; rsize1=size&0xffff; rsize2=size>>16; roffset1=offset&0xffff; roffset2=offset>>16; buf1=FP_OFF(buffer); buf2=FP_SEG(buffer); asm mov dx,filename asm mov ax,3d00h // OPEN w/handle (read only) asm int 21h asm jnc L_0 return 0; L_0: asm mov handle,ax asm mov bx,ax asm xor cx,cx asm xor dx,dx asm mov ax,4202h asm int 21h // SEEK (find file length) asm jc out asm mov flength1,ax asm mov len1,ax asm mov flength2,dx asm mov len2,dx asm mov ax,rsize1 // was a size specified? asm or ax,rsize1 asm jz LOADALL asm mov ax,rsize1 // only load size requested asm mov len1,ax asm mov ax,rsize2 asm mov len2,ax LOADALL: asm mov bx,handle asm mov dx,roffset1 asm mov cx,roffset2 asm mov ax,4200h asm int 21h // SEEK (to file offset) asm jc out asm cmp WORD PTR len2,0 // MULTI-SEGMENTAL? asm je L_2 L_1: asm push ds asm mov bx,handle asm mov cx,8000h // read 32K chunks asm mov dx,buf1 asm mov ax,buf2 asm mov ds,ax asm mov ah,3fh // READ w/handle asm int 21h asm pop ds asm jc out asm add WORD PTR buf2,800h asm sub WORD PTR len1,8000h asm sbb WORD PTR len2,0 asm cmp WORD PTR len2,0 asm ja L_1 asm cmp WORD PTR len1,8000h asm jae L_1 L_2: asm push ds asm mov bx,handle asm mov cx,len1 asm mov dx,buf1 asm mov ax,buf2 asm mov ds,ax asm mov ah,3fh // READ w/handle asm int 21h asm pop ds asm jmp exit out: asm mov WORD PTR flength2,0 asm mov WORD PTR flength1,0 exit: asm mov bx,handle // CLOSE w/handle asm mov ah,3eh asm int 21h return (flength2*0x10000+flength1); } //////////////////////////////////////////////////////////// // // Allocate memory and load file in // //////////////////////////////////////////////////////////// void LoadIn(char *filename,void _seg **baseptr) { char errstr[80]; int handle; long len; if ((handle=open(filename,O_BINARY))==-1) { strcpy(errstr,"Error loading file "); strcat(errstr,filename); Quit(errstr); } len=filelength(handle); close(handle); MMAllocate((memptr *)baseptr,len); LoadFile(filename,MK_FP(*baseptr,0),0,0); }