
uses crt, graph;
var xpos, ypos : integer;
var mwait      : integer;
var temp       : char;
var temploop, temploop2  : integer;
var energy, enerlook    : integer;
var xmove,ymove  : integer;
var bomb, bombx, bomby, bombmx, bombmy : integer;
explodex  : array [1..8] of integer;
explodey  : array [1..8] of integer;
speed     : integer;
var maxcolours, maxx, maxy : integer;
var lxmove, lymove : integer;
GraphDriver : Integer;
GraphMode   : Integer;
LowMode     : Integer;
HighMode    : Integer;
errorcode   : integer;
badx       : array [1..1000] of integer;
bady       : array [1..1000] of integer;
badc    : integer;
badboss : integer;
score   : integer;
addscore : integer;
xcheck, ycheck : integer;
buffer : pointer;
hisize : word;
maxbad : integer;
temp1, temp2 : integer;
temploop3 : integer;
tempi : integer;
badmad : integer;
badman : integer;
mode   : string[8];


{ this is not supposed to be  an example of good or efficient coding. Give
  me a break. ******* }


procedure honk;
begin
     sound(500);
     delay(5);
     nosound;
end;


procedure explode;

var xloop,xsize : integer;

begin
     dec(maxbad);
     for xloop := 200 to 800 do sound(100+random(temploop*5));
     setcolor(green);
     xsize := xloop div 1000;
     rectangle(badx[temploop]-xsize,bady[temploop]-xsize,badx[temploop]+xsize,bady[temploop]+xsize);
     delay(2);
     inc(score);
     inc(energy);
     if temploop = badmad then badmad := 0;
     if (score > 50) and (badboss < 12) then begin
        inc(badboss);
        addscore := addscore + score;
        score := 0;
        for xloop := 200 to 500 do begin
            sound(xloop+random(50));
            delay(1);
        end;
     end;
     setcolor(0);
     for xloop := 4 downto 0 do
         rectangle(badx[temploop]-xloop,bady[temploop]-xloop,badx[temploop]+xloop,bady[temploop]+xloop);
     badx[temploop] := 0;

end;

procedure badon;
begin
for temploop := 400 to 500 do begin
        sound(100+temploop);
        delay(2);
    end;
end;


procedure statusdis;

begin;
      moveto(0,getmaxy-20);
      setcolor(white);
      outtext('Speed:');
      setcolor(black);
      rectangle(55,maxy-15,55+(50),maxy-16);
      setcolor(green);
      rectangle(55,maxy-15,55+(50-speed*2),maxy-16);
      moveto(100,getmaxy-20);
      setcolor(white);
      outtext('Energy:');
      setcolor(black);
      rectangle(155,maxy-15,155+1000 div 25,maxy-16);
      setcolor(green);
      if energy < 400 then setcolor(yellow);
      if energy < 100 then setcolor(red);
      rectangle(155,maxy-15,155+energy div 25,maxy-16);
      setcolor(black);
      line(55,maxy-30,55+333,maxy-30);
      setcolor(red);
      moveto(0,getmaxy-35);
      outtext('Horde:');
      line(55,maxy-30,55+(badboss * 10), maxy-30);
end;


procedure badguys;

begin;

inc (badc);
if badc > (badboss * 70) then badc := 1;

badmad := 0;

if (random(10000) > 9300-badboss*20) then begin
   badmad := random(badboss) + 1;
   if (badx[badmad] = 0) or (badmad = 1) then badmad := 0;
end;

badman := badc;

if badmad <> 0 then badman := badmad;

if (badman = 1) and (maxbad < 50) then begin
   inc(maxbad);
end;


if (badx[badman] = 0) and (badman > badboss) then begin
   tempi := random(badboss)+1;
   badx[badman] := badx[tempi]+random(4)-2;
   if (badx[badman] < 2) or (badx[badman] > maxx-5) then badx[badman] := 0;
   bady[badman] := bady[tempi]+random(4)-2;
   if (bady[badman] < 2) or (bady[badman] > maxy-50) then badx[badman] := 0;
   for temploop := 50 to 200 do sound(random(temploop));
   if badx[badman] = 0 then exit;
   setcolor(red);
   rectangle(badx[badman]-1,bady[badman]-1,badx[badman]+1,bady[badman]+1);
end;

if (badman <= badboss) and (badx[badman] = 0) then begin
   badx[badman] := 10+random(maxx-50);
   bady[badman] := 10+random(maxy-50);
   badon;
end;

   if (badx[badman] < 2) or (badx[badman] > maxx-5) then badx[badman] := 0;
   if (bady[badman] < 2) or (bady[badman] > maxy-50) then badx[badman] := 0;

if badx[badman] > 0 then begin

   setcolor(black);
   rectangle(badx[badman]-1,bady[badman]-1,badx[badman]+1,bady[badman]+1);
   if badx[badman] < xpos then inc(badx[badman]);
   if badx[badman] > xpos then dec(badx[badman]);
   if bady[badman] < ypos then inc(bady[badman]);
   if bady[badman] > ypos then dec(bady[badman]);

   setcolor(red);
   if badman <= badboss then setcolor(red+badman);
   rectangle(badx[badman]-1,bady[badman]-1,badx[badman]+1,bady[badman]+1);

   if (badx[badman]= xpos) and (bady[badman] = ypos) then begin
      setcolor(black);
      for temploop := 100 to 300 do sound(temploop);
      xmove := 0;
      ymove := 0;
      energy := energy - 20;
      statusdis;
   end;
end;
end;


procedure errorhalt;

begin
     writeln('Sorry:',grapherrormsg(errorcode), '  press ENTER...');
     readln;
     halt;
end;

procedure move;
var txmove, tymove : integer;

begin
     temp := readkey;
     if temp = 'G' then begin
        xmove := -1;
        ymove := -1;
     end;
     if temp = 'H' then begin
        xmove := 0;
        ymove := -1;
     end;
     if temp = 'I' then begin
        xmove := 1;
        ymove := -1;
     end;
     if temp = 'K' then begin
        xmove := -1;
        ymove := 0;
     end;
     if temp = 'M' then begin
        xmove := 1;
        ymove := 0;
     end;
     if temp = 'O' then begin
        xmove := -1;
        ymove := 1;
     end;
     if temp = 'P' then begin
        xmove := 0;
        ymove := 1;
     end;
     if temp = 'Q' then begin
        xmove := 1;
        ymove := 1;
     end;
     txmove := xmove;
     tymove := ymove;
     if (xmove = 0) and (ymove = 0) then begin
        txmove := lxmove;
        tymove := lymove;
     end;
     if (temp = 'R') and (bomb = 0) then begin
        bombx := xpos+xmove*5;
        bomby := ypos+ymove*5;
        energy := energy - 10;
        bomb := getmaxx div 7;
        if (xmove=0) and (ymove=0) then bomb := 1;
        bombmx := xmove;
        bombmy := ymove;
        for temploop := 200 to 600 do begin
            sound(temploop);
        end;
        nosound;
     end;
     if temp = 'S' then begin
        dec(energy);
        setcolor(yellow);
        line(xpos+(txmove*5),ypos+(tymove*5),xpos+txmove*16,ypos+tymove*16);

for temploop := 1 to maxbad do begin
   sound(temploop*2 + 100);
   setcolor(yellow);
   for temploop2 := 1 to 16 do begin
       xcheck := xpos+(txmove*5)+(temploop2*txmove);
       ycheck := ypos+(tymove*5)+(temploop2*tymove);
       if (badx[temploop] = xcheck) and (bady[temploop] = ycheck) then begin
          explode;
       end;
   end;

end;
        setcolor(black);
        line(xpos+txmove*5,ypos+tymove*5,xpos+txmove*16,ypos+tymove*16);
     end;


end;


begin
     sound(200);
     explodex[1] := 0;
     explodex[2] := 1;
     explodex[3] := 1;
     explodex[4] := 1;
     explodex[5] := 0;
     explodex[6] := -1;
     explodex[7] := -1;
     explodex[8] := -1;

     explodey[1] := -1;
     explodey[2] := -1;
     explodey[3] := 0;
     explodey[4] := 1;
     explodey[5] := 1;
     explodey[6] := 1;
     explodey[7] := 0;
     explodey[8] := -1;

for temploop := 1 to 1000 do begin
    badx[temploop] := 0;
    bady[temploop] := 100;
end;

  nosound;
  score := 0;
  badmad := 0;
  badman := 1;
  lxmove := 0;
  lymove := 0;
  maxbad := 5;
  clrscr;
  addscore := 0;
  badboss := 1;
  badx[1] := 10;
  bady[1] := 10;
  badx[2] := 200;
  bady[2] := 200;
  speed := 6;
  energy := 1000;
  mwait := 5;
  xpos := 100;
  ypos := 100;
  xmove := 0;
  ymove := 0;
  bomb := 0;
  badc := 1;

  for temploop := 1 to 54 do begin
      gotoxy(temploop,1);
      textcolor(random(16));
      writeln(' Ugly Red Things from Hell');
      for temploop2 := 200 to 210 do begin
          sound(500-temploop2+temploop*50);
          delay(1);
      end;
  nosound;
end;

textcolor(green);
writeln('Instructions:');
textcolor(cyan);
writeln;
writeln('     Destroy the yucky horde by long-range bombing them with the INS key,');
writeln('     short-range lasering them with the DEL key, or nukeing them with');
writeln('     RETURN. Each weapon costs energy, the more powerful the more energy');
writeln('     it uses. You move around with the arrow keys in all 8 directions,');
writeln('     and come to a stop with the SPACE key. You can slow down or speed up');
writeln('     with the plus and minus keys.');
writeln;
writeln('     If you are running out of energy, slow down and you will recharge.');
gotoxy(1,25);
textcolor(red+blink);
write('         ESC quits the game - Make sure your NumLock is off!');



textcolor(yellow);
temp := #1;
while temp <> #0 do begin
      gotoxy(1,14);
      textcolor(yellow);
      writeln('Choose Graphics Mode');
      textcolor(green);
      writeln;
      writeln('         1 ...... Default (Autodetect CGA, EGA, VGA, Herc');
      writeln('         2 ...... Force CGA');
      writeln('         3 ...... Force EGA');
      writeln('         4 ...... Force VGA');
      writeln('         5 ...... Force Monochrome (Hercules)');
      writeln('       ESC ...... QUIT');
      writeln;
      textcolor(yellow);
      write('Your choice: ');
      gotoxy (42,2);
      writeln('U R T H');
      while keypressed <> true do begin
            gotoxy(51+random(2),1+random(3));
            textcolor(random(16));
            writeln('  Ugly Red Things from Hell ' );
      end;
      temp := readkey;

      case temp of

      #27 : begin
                 gotoxy(1,25);
                 textcolor(white);
                 writeln;
                 halt;
            end;

      '1' : begin
                 mode := 'Detect';
                 temp := #0;
                 GraphDriver := detect;
            end;

      '2' : begin
                 mode := 'CGA';
                 honk;
                 temp := #0;
                 graphdriver := 1;
                 graphmode := 4;
            end;
      '3' : begin
                 mode := 'EGA';
                 temp := #0;
                 honk;
                 graphdriver := 3;
                 graphmode := 1;
            end;
      '4' : begin
                 mode := 'VGA';
                 temp := #0;
                 honk;
                 graphdriver := 9;
                 graphmode := 2;
            end;
      '5' : begin
                 mode := 'Herc';
                 temp := #0;
                 honk;
                 graphdriver := 7;
                 graphmode := 0;
            end;

      end;
end;


  InitGraph(graphdriver,graphmode, '');
  if GraphResult <> grOk then errorhalt;
  GetModeRange(Graphdriver, LowMode, HighMode);
  SetGraphMode(highmode);
  writeln('Press ESC you ninny, next time try a different graphics mode.');
  setcolor(white);
  circle(4,4,2);
  randomize;
  getmem(buffer,hisize);
  getimage(2,2,6,6,buffer^);
  putimage(2,2,buffer^,1);
  maxx := getmaxx;
  maxy := getmaxy;
  maxcolours := getmaxcolor;
  setcolor(yellow);
  rectangle(0,0,maxx,maxy-42);
  statusdis;
  putimage(xpos,ypos,buffer^,1);

     while energy > 0 do begin
          maxbad := (badboss * 70);
          badguys;
          sound(10+bomb*50);
          nosound;
          dec(mwait);
          temp := #1;
          if mwait = 0 then begin;
             mwait := speed;
             if keypressed = true then temp := readkey;
             if temp = #0 then move;
             if temp = #13 then begin
                for temploop := 1 to maxbad do begin
                    if badx[temploop] <> 0 then explode;
                end;
                energy := energy - 500;
             end;
             if (temp = #32) then begin
                if (xmove <> 0) or (ymove <> 0) then begin
                   lxmove := xmove;
                   lymove := ymove;
                   xmove := 0;
                   ymove := 0;
                   for temploop := 200 downto 100 do begin
                       sound(temploop);
                       delay(1);
                       nosound;
                       end;
                end;
             end;
             if temp = #27 then energy := -1;
             if temp = 'E' then energy := energy + 100;
             if (temp = '+') and (speed > 2) then begin
                dec(speed);
                if speed = 18 then begin
                   setcolor(black);
                   outtextxy(maxx-90,maxy-36,'Recharging');
                end;
                statusdis;
             end;
             if (temp = '-') and (speed <25 ) then begin
                if speed > 18 then begin
                   outtextxy(maxx-90,maxy-36,'Recharging');
                   sound(400);
                end;
                inc(speed);
                statusdis;
             end;
             if (speed > 18) and (energy < 1000) then inc(energy);
             if (xmove <> 0) or (ymove <> 0) then begin
             putimage(xpos,ypos,buffer^,1);                       { *** 2 }
                if xpos + xmove < 6 then xmove := - xmove;
                if xpos + xmove > getmaxx-8 then xmove := -xmove;
                if ypos + ymove < 6 then ymove := -ymove;
                if ypos + ymove > getmaxy-46 then ymove := -ymove;
                if (xpos + xmove > 5) and (xpos + xmove < getmaxx-7) then
                   xpos := xpos + xmove;
                if (ypos + ymove > 5) and (ypos + ymove < getmaxy-39) then
                   ypos := ypos + ymove;
                putimage(xpos,ypos,buffer^,1);
                if enerlook <> energy div 100 then begin
                   enerlook := energy div 100;
                   statusdis;

                end;
             end;
          end;
          if (bomb > 0) then begin
             putpixel(bombx,bomby,0);
             if (bombx + bombmx > 2) and (bombx + bombmx < getmaxx-2) then bombx := bombx + bombmx;
             if (bomby + bombmy > 2) and (bomby + bombmy < getmaxy-45) then bomby := bomby + bombmy;
             dec(bomb);
             if bomb > 0 then begin
                putpixel(bombx,bomby,7);
             end
             else
                 for temploop3 := 0 to 7 do begin
                     sound(250+temploop3*50);
                     for temploop2 := 1 to 12 do begin
                         temp1 := (bombx+explodex[temploop2]*temploop3);
                         temp2 := (bomby+explodey[temploop2]*temploop3);
                         if temp1 > maxx-2 then temp1 := maxx-2;
                         if temp1 < 3 then temp1 := 3;
                         if temp2 > maxy-43 then temp2 := maxy-50;
                         if temp2 < 3 then temp2 := 3;
                         putpixel(temp1,temp2,2+random(2+5));
                         for temploop := 1 to maxbad do begin
                             if (badx[temploop] = temp1) and (bady[temploop] = temp2) then explode;
                         end;
                     end;

                     for temploop2 := 1 to 12 do begin
                         temp1 := (bombx+explodex[temploop2]*temploop3);
                         temp2 := (bomby+explodey[temploop2]*temploop3);
                         if temp1 > maxx-2 then temp1 := maxx-2;
                         if temp1 < 3 then temp1 := 3;
                         if temp2 > maxy-43 then temp2 := maxy-50;
                         if temp2 < 3 then temp2 := 3;
                         putpixel(temp1,temp2,0);
                     end;


                 end;

          end;

     end;


gotoxy(1,25);
closegraph;
nosound;
writeln;
textcolor(red);
if temp <> #27 then writeln('You are out of energy.');
writeln;
textcolor(blue);
writeln('Your final score: ',addscore+score,',000 points.');
writeln;
textcolor(white);
writeln('Press a key ...');
temp := readkey;
nosound;
end.

