4 extern char far TEDCHAR,far VGAPAL;
6 void Quit(char *string);
7 void drawchar(int x,int y,int chr);
8 void centerwindow (int width, int height);
10 int win_xl,win_yl,win_xh,win_yh;
11 int screencenterx = 19,screencentery = 11;
12 unsigned char keydown[256];
13 unsigned leftedge,yshift,xormask,MouseStatus,sx,sy;
14 void interrupt (*oldint9) ()=NULL;
15 enum {false,true} boolean;
16 memptr CGAfont,VGAfont;
17 unsigned doubled[256];
19 // Special vars to handle EGA3 mouse mode
24 ////////////////////////////////////////////////////////////////////
26 // Return a file's length
28 ////////////////////////////////////////////////////////////////////
29 long filelen(char *filename)
34 if ((handle=open(filename,O_BINARY))==-1)
37 size=filelength(handle);
42 ////////////////////////////////////////////////////////////////////
46 ////////////////////////////////////////////////////////////////////
47 void WaitVBL(int times)
55 asm test al,00001000b //;look for vbl
60 asm test al,00001000b //;look for vbl
67 ////////////////////////////////////////////////////////////////////
70 // Called for every keypress. Keeps track of which keys are down, and passes
71 // the key on to DOS after clearing the dos buffer (max 1 char in buffer).
73 ////////////////////////////////////////////////////////////////////
74 void interrupt Int9ISR ()
76 int key = inportb (0x60); /* get the key pressed */
79 keydown [key-128] = false; /* break scan code */
82 keydown [key] = true; /* make scan code */
83 poke (0x40,0x1c,peek(0x40,0x1a)); /* clear the bios key buffer */
94 oldint9 (); /* give it to DOS */
104 outport (0x20,0x20); /* tell the int manager we got it */
108 ////////////////////////////////////////////////////////////////////
111 // Clears the keydown array and installs the INT 9 ISR if it isn't already
114 ////////////////////////////////////////////////////////////////////
117 void far *vect = getvect (9);
120 for (i=0;i<128;i++) /* clear our key down table */
123 poke (0x40,0x1c,peek(0x40,0x1a)); /* clear the bios key buffer */
125 if ( &Int9ISR != vect ) /* is our handler allready set up? */
133 ////////////////////////////////////////////////////////////////////
136 // Sets the int 9 vector back to oldint 9
138 ////////////////////////////////////////////////////////////////////
146 ////////////////////////////////////////////////////////////////////
149 // Clears out the bios buffer and zeros out the keydown array
151 ////////////////////////////////////////////////////////////////////
152 void clearkeys (void)
163 ////////////////////////////////////////////////////////////////////
167 ////////////////////////////////////////////////////////////////////
171 unsigned char far *vector;
173 if ((vector=MK_FP(peek(0,0x33*4+2),peek(0,0x33*4)))==NULL) return 0;
176 return MouseStatus = 0;
184 // Set CGA mouse cursor (normal one sucks)
188 static unsigned CGAcursor[]=
190 0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x000f,0x0c03,0x3c03,
191 0xff03,0xffff,0xffff,0xffff,0xffff,0xffff,
193 0xf000,0xcc00,0xc300,0xc0c0,0xc030,0xc00c,0xc03f,0xcc30,0xf30c,0xc30c,
194 0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000
199 _DX=FP_OFF(CGAcursor);
205 return MouseStatus = 1;
209 void MouseOrigin(int x,int y)
211 if (!MouseStatus) return;
220 void MouseLimits(int xmin,int xmax,int ymin,int ymax)
222 if (!MouseStatus) return;
237 if (!MouseStatus) return;
247 if (!MouseStatus) return;
255 int MouseButton(void)
259 if (!MouseStatus) return 0;
262 int86(0x33,®s,®s);
268 void MouseCoords(int *x,int *y)
276 int86(0x33,®s,®s);
285 /////////////////////////
288 // Prints a string at sx,sy. No clipping!!!
290 /////////////////////////
292 void print (const char *str)
296 while ((ch=*str++) != 0)
305 drawchar (sx++,sy,ch);
307 void fprint (const char huge *str)
311 while ((ch=*str++) != 0)
320 drawchar (sx++,sy,ch);
323 ////////////////////////////////////////////////////////////////////
327 ////////////////////////////////////////////////////////////////////
328 void printhexb(unsigned char value)
331 char hexstr[16]="0123456789ABCDEF",str[2]="";
333 for (loop=0;loop<2;loop++)
335 str[0]=hexstr[(value>>(1-loop)*4)&15];
340 ////////////////////////////////////////////////////////////////////
344 ////////////////////////////////////////////////////////////////////
345 void printhex(unsigned value)
349 printhexb(value&0xff);
353 ////////////////////////////////////////////////////////////////////
357 ////////////////////////////////////////////////////////////////////
358 void printint(unsigned value)
362 ultoa((unsigned long)value,temp,10);
367 ////////////////////////////////////////////////////////////////////
371 ////////////////////////////////////////////////////////////////////
372 void printbin(unsigned value)
377 for (loop=0;loop<16;loop++)
378 if ((value>>15-loop)&1) print("1"); else print("0");
382 ////////////////////////////////////////////////////////////////////
386 ////////////////////////////////////////////////////////////////////
387 unsigned inputint(int numchars)
389 char string[18]="",digit,hexstr[16]="0123456789ABCDEF";
390 unsigned value,loop,loop1;
392 if (!input(string,numchars))
399 digits=strlen(string)-2;
400 if (digits<0) return 0;
402 for (value=0,loop1=0;loop1<=digits;loop1++)
404 digit=toupper(string[loop1+1]);
405 for (loop=0;loop<16;loop++)
406 if (digit==hexstr[loop])
408 value|=(loop<<(digits-loop1)*4);
413 else if (string[0]=='%')
417 digits=strlen(string)-2;
418 if (digits<0) return 0;
420 for (value=0,loop1=0;loop1<=digits;loop1++)
422 if (string[loop1+1]<'0' || string[loop1+1]>'1') return 0;
423 value|=(string[loop1+1]-'0')<<(digits-loop1);
426 else value=atoi(string);
431 ////////////////////////////////////////////////////////////////////
433 // line input routine
435 ////////////////////////////////////////////////////////////////////
436 int input(char *string,int max)
443 if ((key==127 || key==8)&&count>0)
450 if (key>=' ' && key<='z' && count<max)
452 *(string+count++)=key;
453 drawchar(sx++,sy,key);
456 } while (key!=27 && key!=13);
458 for (loop=count;loop<max;loop++) *(string+loop)=0;
460 while(keydown[1]); // don't let ESC repeat
464 while(keydown[0x1c]);
470 void bar (int xl, int yl, int xh, int yh, int ch)
479 /////////////////////////
482 // Flash a cursor at sx,sy and waits for a user bioskey
484 /////////////////////////
493 while (!(key = bioskey(1)) && cycle<11)
495 drawchar (sx,sy,cycle++);
499 drawchar (sx,sy,' ');
500 return bioskey(0); // take it out of the buffer
504 ////////////////////////////////////////////////////////////////////
508 ////////////////////////////////////////////////////////////////////
509 void drawchar(int x,int y,int chr)
513 case CGA: CGAcharout(x,y,chr); break;
515 case EGA2: EGAcharout(x,y,chr,videomode); break;
516 case VGA: VGAcharout(x,y,chr);
520 ////////////////////////////////////////////////////////////////////
524 ////////////////////////////////////////////////////////////////////
525 void setvideo(video vid)
528 // create CGA font (if not already created)
530 if (vid==CGA && !CGAfont)
532 unsigned char huge *oldfont=MK_FP(FP_SEG(&TEDCHAR),FP_OFF(&TEDCHAR));
533 unsigned i,j,huge *newfont;
536 print("Creating CGA font...");
538 MMAllocate(&CGAfont,2048);
539 newfont=MK_FP(CGAfont,0);
543 (unsigned)*(newfont+i*8+j)=doubled[*(oldfont+i*8+j)]; //color=|0xaaaa;
547 // OR create VGA font (if not already created)
549 if (vid==VGA && !VGAfont)
551 unsigned char huge *oldfont=MK_FP(FP_SEG(&TEDCHAR),FP_OFF(&TEDCHAR)),
554 unsigned char bitbyte[2]={0,0xff}; // colors={0x7e,0x78};
557 print("Creating VGA font...");
559 MMAllocate(&VGAfont,0x2000);
560 newfont=MK_FP(VGAfont,0);
565 *(newfont+i*64+j*8+k)=bitbyte[(*(oldfont+i*8+j)>>(7-k))&1];
568 // Now, change video modes!
572 case TEXT: _AX=3; break;
605 // Set CGA mouse cursor (normal one sucks)
609 static unsigned CGAcursor[]=
611 0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x000f,0x0c03,0x3c03,
612 0xff03,0xffff,0xffff,0xffff,0xffff,0xffff,
614 0xf000,0xcc00,0xc300,0xc0c0,0xc030,0xc00c,0xc03f,0xcc30,0xf30c,0xc30c,
615 0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000
620 _DX=FP_OFF(CGAcursor);
627 // Move EGA font into LATCH memory!
629 if (vid==EGA1 || vid==EGA2)
631 unsigned i,s=FP_SEG(&TEDCHAR),o=FP_OFF(&TEDCHAR);
633 outport(GCindex,GCmode);
636 outport(SCindex,SCmapmask | (1<<i)*256);
637 movedata(s,o+i*0x400,0xaf00,0,0x400);
642 // OR set the VGA palette
644 if (vid==VGA) // set VGA palette
656 ////////////////////////////////////////////////////////////////////
658 // Quit the fuck outta here!
660 ////////////////////////////////////////////////////////////////////
661 void Quit(char *string)
665 poke(0,0x41a,peek(0,0x41c)); // clear keyboard
668 printf("TED5 ERROR: %s",string);
671 printf("Thanks for using TED5!");
677 //////////////////////////
680 // draws a bordered window and homes the cursor
682 //////////////////////////
684 void drawwindow (int xl, int yl, int xh, int yh)
690 win_yh=yh; // so the window can be erased
693 for (x=xl+1;x<xh;x++)
696 for (y=yl+1;y<yh;y++)
699 for (x=xl+1;x<xh;x++)
704 for (x=xl+1;x<xh;x++)
708 sx = leftedge = xl+1;
712 ////////////////////////////
715 // clears out the last window and it's border to spaces
717 ///////////////////////////
719 void erasewindow (void)
721 bar (win_xl,win_yl,win_xh,win_yh,' ');
724 /////////////////////////////
727 // Centers a drawwindow of the given size
729 /////////////////////////////
731 void centerwindow (int width, int height)
733 int xl = screencenterx-width/2;
734 int yl = screencentery-height/2;
736 drawwindow (xl,yl,xl+width+1,yl+height+1);
739 ///////////////////////////////
742 // Grows the window outward
744 ///////////////////////////////
745 void expwinh (int width, int height)
748 expwinh (width-2,height);
751 centerwindow (width,height);
754 void expwinv (int width, int height)
757 expwinv (width,height-2);
760 centerwindow (width,height);
762 void expwin (int width, int height)
767 expwin (width-2,height-2);
769 expwinh (width-2,height);
773 expwinv (width,height-2);
776 centerwindow (width,height);
780 ////////////////////////////////////////////////////////////
782 // Save a *LARGE* file from a FAR buffer!
783 // by John Romero (C) 1990 Gamer's Edge
785 ////////////////////////////////////////////////////////////
786 void SaveFile(char *filename,char huge *buffer,long offset,long size)
788 unsigned int handle,buf1,buf2,offlo,offhi,sizelo,sizehi;
802 asm mov ax,3d02h // OPEN w/handle (read only)
816 asm int 21h // SEEK (to file offset)
824 asm mov ax,3c00h // CREATE w/handle (read only)
833 asm cmp WORD PTR sizehi,0 // larger than 1 segment?
844 asm mov ah,40h // WRITE w/handle
848 asm add WORD PTR buf2,800h // bump ptr up 1/2 segment
849 asm sub WORD PTR sizelo,8000h // done yet?
850 asm sbb WORD PTR sizehi,0
851 asm cmp WORD PTR sizehi,0
853 asm cmp WORD PTR sizelo,8000h
864 asm mov ah,40h // WRITE w/handle
870 asm mov bx,handle // CLOSE w/handle
876 ////////////////////////////////////////////////////////////
878 // Load a *LARGE* file into a FAR buffer!
879 // by John Romero (C) 1990 Gamer's Edge
881 ////////////////////////////////////////////////////////////
882 unsigned long LoadFile(char *filename,char huge *buffer,long offset,long size)
884 unsigned handle,flength1=0,flength2=0,buf1,buf2,len1,len2,
885 rsize1,rsize2,roffset1,roffset2;
889 roffset1=offset&0xffff;
895 asm mov ax,3d00h // OPEN w/handle (read only)
908 asm int 21h // SEEK (find file length)
916 asm mov ax,rsize1 // was a size specified?
920 asm mov ax,rsize1 // only load size requested
931 asm int 21h // SEEK (to file offset)
934 asm cmp WORD PTR len2,0 // MULTI-SEGMENTAL?
941 asm mov cx,8000h // read 32K chunks
945 asm mov ah,3fh // READ w/handle
950 asm add WORD PTR buf2,800h
951 asm sub WORD PTR len1,8000h
952 asm sbb WORD PTR len2,0
953 asm cmp WORD PTR len2,0
955 asm cmp WORD PTR len1,8000h
966 asm mov ah,3fh // READ w/handle
973 asm mov WORD PTR flength2,0
974 asm mov WORD PTR flength1,0
978 asm mov bx,handle // CLOSE w/handle
982 return (flength2*0x10000+flength1);
987 ////////////////////////////////////////////////////////////
989 // Allocate memory and load file in
991 ////////////////////////////////////////////////////////////
992 void LoadIn(char *filename,void _seg **baseptr)
998 if ((handle=open(filename,O_BINARY))==-1)
1000 strcpy(errstr,"Error loading file ");
1001 strcat(errstr,filename);
1005 len=filelength(handle);
1007 MMAllocate((memptr *)baseptr,len);
1008 LoadFile(filename,MK_FP(*baseptr,0),0,0);