/* *********************************************************************** * * * Graphics Animation Program * * * * By * * * * Larry Sharp * * * * * * (c) 1991 Larry Sharp * * * * * * Original Turbo Pascal version (c) 1991,1992 Christopher D. Watkins * * * *********************************************************************** Compile using Large memory model Maximum of 30 Cels per Animation Sequence at 160 x 100 resolution */ #include "stdio.h" #include "dos.h" #include "string.h" #include "malloc.h" #include "mem.h" #include "conio.h" #include "defs.h" union REGS reg; /* Global Variables */ struct SREGS inreg; char File_Name[81]; Byte n, y, key, B_Col; Byte Num_Cels; int Direction, Flip, CP; int D_Rate, Old_D_Rate; Word Cel_Off[3000]; Word Cel_Seg[3000]; Word Window_Offsets[100]; Word Screen_Offsets[200]; Palette_Register Pal_Array; static Byte far *Screen; static Byte far *Cel_Buf; /* *********************************************************************** * * * Graphics Routines * * * *********************************************************************** */ void Set_Mode(Byte Mode) { reg.h.ah=0; reg.h.al=Mode; int86(0x10,®,®); } void Init_Screen() { Byte y; for(y=0; y<200; y++) Screen_Offsets[y]=320*y; } void Plot(int x, int y, Byte color) { Word Offset, Page; char far *address; if(!((x<0) || (y<0) || (x>(319)) || (y>(200)))) { Offset = Screen_Offsets[y] + x; address = (char far *) (0xA0000000L + Offset); *address = color; } } void Set_Palette(Palette_Register Hue) { reg.x.ax=0x1012; segread(&inreg); inreg.es=inreg.ds; reg.x.bx=0; reg.x.cx=256; reg.x.dx=(int)&Hue[0]; int86x(0x10,®,®,&inreg); } void Init_Graphics() { Init_Screen(); Set_Mode(19); Set_Palette(Pal_Array); } void Exit_Graphics() { sound(1000); delay(500); nosound(); Set_Mode(3); } void Set_Text_Screen(int tc, int tb) { textcolor(tc); textbackground(tb); clrscr(); } /* *********************************************************************** * * * Memory Routines * * * *********************************************************************** */ void Allocate_Memory() { if((Cel_Buf=farcalloc(32, 16000))==NULL) { printf("Not enough memory!\n\nHit any key to exit...."); getch(); exit(1); } } void Free_Memory() { farfree(Cel_Buf); } Word Max(Word n1, Word n2) { return((n1>n2) ? n1 : n2); } Byte Get_Key() { Byte k; key=getch(); return(key); } void Get_ANI_File_Name() { Byte x, y; textcolor(YELLOW); textbackground(BLUE); gotoxy(1, 8); cprintf("Enter File Name -> "); x=wherex(); y=wherey(); textcolor(WHITE+BLINK); cprintf("%s", "SPHRPLAN"); textcolor(YELLOW); gotoxy(x, y); while(!(kbhit())); cprintf(" "); gotoxy(x, y); gets(File_Name); if(!(strcmp(File_Name, ""))) strcpy(File_Name, "SPHRPLAN"); strupr(File_Name); strcat(File_Name, ".ANI"); gotoxy(1, 8); printf(" "); textcolor(WHITE+BLINK); gotoxy(1, 8); cprintf("Loading "); textcolor(YELLOW); cprintf("%s", File_Name); } void Init_Cels() { DWord tmp, NCel_Buf; Word n, y, Seg; tmp=NCel_Buf=(DWord) Cel_Buf; Seg=(Word)((tmp>>16)&65535); for(n=0; n<30; n++) { for(y=0; y<100; y++) { tmp=(DWord) NCel_Buf; tmp+=(DWord)((n*16000)+(y*160)); Cel_Off[(n*100)+y]=(Word)(tmp&65535); if((Cel_Off[(n*100)+y]+160)38; i--) { gotoxy(i, 2); cprintf("by "); delay(15); } textcolor(F_Colors[2]); textbackground(B_Colors[2]); for(i=23; i>2; i--) { gotoxy(34, i); cprintf("Larry Sharp"); gotoxy(34, i+1); cprintf(" "); delay(15); } textcolor(LIGHTGRAY); gotoxy(35, 17); cprintf("DIRECTION"); gotoxy(37, 20); cprintf("SPEED"); gotoxy(33, 23); cprintf("FRAME ADVANCE"); textbackground(BLACK); textcolor(LIGHTRED); gotoxy(16, 18); cprintf(" Fwd Rvs Flip Up Flip Down "); gotoxy(16, 21); cprintf(" Speed Up Slow Down <10 >10 Quit "); gotoxy(16, 24); cprintf(" Forward Advance Reverse Advance Pause "); textcolor(WHITE); gotoxy(17, 18); cprintf("Rgt"); gotoxy(27, 18); cprintf("Lft"); gotoxy(38, 18); cprintf("Up"); gotoxy(51, 18); cprintf("Dwn"); gotoxy(17, 21); cprintf("+"); gotoxy(29, 21); cprintf("-"); gotoxy(42, 21); cprintf("*"); gotoxy(49, 21); cprintf("/"); gotoxy(56, 21); cprintf("Esc"); gotoxy(17, 24); cprintf(">"); gotoxy(35, 24); cprintf("<"); gotoxy(53, 24); cprintf("Space"); } void Find_Brightest_Color() { Word h1, h2, h3, i; Byte c; c=0; h3=h1=(Pal_Array[0].Red+Pal_Array[0].Grn+Pal_Array[0].Blu); for(i=1; i<256; i++) { h2=(Pal_Array[i].Red+Pal_Array[i].Grn+Pal_Array[i].Blu); h3=Max(h1, h2); if(h3==h2) { c=i; h1=h2; } } B_Col=c; } void H_Line(Word x1, Word x2, Byte y1, Byte c) { Word i; for(i=x1; i<=x2; i++) { Plot(i, y1, c); } } void V_Line(Word x1, Byte y1, Byte y2, Byte c) { Word i; for(i=y1; i<=y2; i++) { Plot(x1, i, c); } } void Draw_Window_Frame() { H_Line(79, 240, 49, B_Col); H_Line(79, 240, 150, B_Col); V_Line(79, 49, 150, B_Col); V_Line(240, 49, 150, B_Col); } void Draw_D_Meter() { H_Line(32, 289, 189, B_Col); /* Draw Rectangular Meter */ H_Line(32, 289, 199, B_Col); V_Line(32, 189, 199, B_Col); V_Line(289, 189, 199, B_Col); V_Line(32, 183, 187, B_Col); /* Draw '+' */ H_Line(30, 34, 185, B_Col); H_Line(287, 291, 185, B_Col); /* Draw '-' */ } void Update_D_Meter(int D_Rate) { Word i; if(Old_D_Rate>D_Rate) { for(i=Old_D_Rate; i>D_Rate; i--) V_Line((i+33), 190, 198, 0); } else { for(i=Old_D_Rate; i<=D_Rate; i++) V_Line((i+33), 190, 198, 24); } } void Init_D_Meter() { D_Rate=50; /* Initial Delay Rate */ Old_D_Rate=0; Find_Brightest_Color(); Draw_Window_Frame(); Draw_D_Meter(); Update_D_Meter(D_Rate); Old_D_Rate=D_Rate; } void Animate() { Byte n, y, k, tmp, NC, Nl; Word Del; Word l1; int LP; NC=Num_Cels-1; CP=0; Nl=99; LP=0; while(key!=27) /* Animate until Escape key hit */ { for(n=0; nNl) LP=0; } } if(Direction) { ++CP; if(CP>NC) CP=0; } else { --CP; if(CP<0) CP=NC; } for(Del=0; Del<(D_Rate*200); Del++); for(Del=0; Del<(D_Rate*200); Del++); if(kbhit()) /* Check for key stroke */ { k=Get_Key(); /* Get key stroke */ switch(toupper(k)) { case '+' : Old_D_Rate=D_Rate; /* Faster by 1 */ --D_Rate; if(D_Rate<0) D_Rate=0; Update_D_Meter(D_Rate); break; case '-' : Old_D_Rate=D_Rate; /* Slower by 1 */ ++D_Rate; if(D_Rate>255) D_Rate=255; Update_D_Meter(D_Rate); break; case '*' : Old_D_Rate=D_Rate; /* Faster by 10 */ D_Rate-=10; if(D_Rate<0) D_Rate=0; Update_D_Meter(D_Rate); break; case '/' : Old_D_Rate=D_Rate; /* Slower by 10 */ D_Rate+=10; if(D_Rate>255) D_Rate=255; Update_D_Meter(D_Rate); break; case 'M' : if(!Direction) /* Forward */ { Direction=1; n=NC-n; } break; case 'K' : if(Direction) /* Reverse */ { Direction=0; n=NC-n; } break; case 'H' : if(Flip) /* Forward */ { Flip=0; LP=0; } break; case 'P' : if(!Flip) /* Reverse */ { Flip=1; LP=Nl; } break; } k=0; /* Set key back to 0 */ } } } } void Load_Cels() { FILE *In_File; if((In_File=fopen(File_Name,"rb"))==NULL) /* Open animation file */ { Exit_Graphics(); printf("Can't open Animation File %s!\n\nHit any key to exit....", File_Name); getch(); Free_Memory(); exit(1); } Num_Cels=getc(In_File); /* Get # of Cels in sequence */ printf("\n\nThere are %u Cels in this Animation sequence.\n", Num_Cels); if(Num_Cels>30) /* Maximum of 30 Cels */ { printf("\nTruncating to 30 Cels....\n"); Num_Cels=30; } fread(Pal_Array, 1, 768, In_File); /* Load Palette for animation */ for(n=0; n