[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]

    {
    Here is a little something for all you pyromaniacs, and demo coders out there.

    I got my hands on Jare's fire code and thought it was pretty cool, so I made
    my own fire program. Although it didn't turn out like I thought it would (like
    Jare's) what I have is (at least I think so) something that looks more
    realistic.

    This program was completely written by myself and was inspired by Jare's fire
    code (available on Internet FTP at ftp.eng.ufl.edu  pub/msdos/demos/programming
    /source). A 386 computer is required (Double Word copies are used), but a 486
    is highly recommended, as 28800 pixels are calculated each frame (I use
    standard mode 13h). The entire source is Pascal/Inline asm and was written
    using Turbo Pascal v6.0.    I hope you like it.

    { **** Program starts here ******** }

    Program Phire;
    {$G+}    { Enable 286 instructions }
    { coded by Phred  7/23/94     aka Alex Chalfin    }
    {               Internet: achalfin@uceng.uc.edu   }
    { A fast computer is HIGHLY recommended.          }
    { Inspired by Jare's fire code                    }

    Var
      Screen : Array[0..63999] of Byte ABSOLUTE $A000:$0000; { the VGA screen }
      VScreen : Array[0..63999] of Byte;                { an offscreen buffer }
      Lookup : Array[0..199] of Word;    { an Offset lookup table }

    Procedure SetPalette; Near;
    { Sets the Palette }

    Var
      p : Array[0..767] of Byte;
      x : integer;

    Begin
      for x := 0 to 255 do            { Generate fade from orange to black }
        Begin
          p[x*3] := (x * 63) Shr 8;
          P[x*3+1] := (x * 22) Shr 8;
          P[x*3+2] := 0;
        End;
      Port[$3C8] := 0;
      For x := 0 to 255 do        { Set the palette }
        Begin
          Port[$3C9] := P[x*3];
          Port[$3C9] := P[x*3+1];
          Port[$3C9] := P[x*3+2];
        End;
    End;

    Procedure Burnin_Down_The_House;

    Var
      c : Integer;

    Begin
      Randomize;
      Repeat
        For c := 0 to 319 do    { Setup bottom line "hot spots" }
          If Random(4) = 1
            Then VScreen[LookUp[199] + c] := Random(3) * 255;
        Asm
          MOV  CX,28800         { Number of pixels to calculate }
          PUSH CX               { Store count on stack }
          MOV  AX,Offset VScreen
          PUSH AX               { Store value on stack }
          MOV  SI,AX
          MOV  BX,199
          SHL  BX,1
          MOV  AX,Word Ptr [LookUp + BX]
          ADD  SI,AX
          DEC  SI            { DS:SI := VScreen[LookUp[198]+319] }
         @Looper:
          XOR  AX,AX
          XOR  BX,BX
          MOV  AL,DS:[SI+319]
          ADD  BX,AX
          MOV  AL,DS:[SI+320]
          ADD  BX,AX
          MOV  AL,DS:[SI+321]
          ADD  BX,AX
          MOV  AL,DS:[SI]
          ADD  BX,AX    { Average the three pixels below and the one that its on}
          SHR  BX,2     { Divide by 4 }
          JZ  @Skip
          DEC  BX       { Subtract 1 if value > 0 }
         @Skip:
          MOV  DS:[SI],BL  { Store pixel to screen }
          DEC  SI          { Move to next pixel }
          DEC  CX
          JNZ @Looper
        { Copy the screen Buffer using Double Word copies }
          MOV  BX,110
          SHL  BX,1
          MOV  AX,Word Ptr [LookUp + BX]
          MOV  DX,AX
          POP  SI        { Restore starting offset of VScreen  }
          MOV  AX,$A000
          MOV  ES,AX     { DS:SI = starting location in buffer }
          XOR  DI,DI     { ES:DI = Starting location in screen }
          ADD  SI,DX
          ADD  DI,DX
          POP  CX        { Retrive Count off the stack }
          SHR  CX,2      { divide by 4 to get # of double words.              }
         db 66h          { Since TP won't allow 386 instructions, fake it.    }
          REP  MOVSW     { This translates into REP MOVSD (move double words) }
        End;
      Until Port[$60] = 1;   { Until ESC is pressed }
    End;

    Begin
      Asm              { Initialize mode 13h VGA mode }
        MOV  AX,13h
        INT  10h
      End;
      For LookUp[0] := 1 to 199 do            { Calculate lookup table }
        LookUp[LookUp[0]] := LookUp[0] * 320;
      LookUp[0] := 0;
      SetPalette;
      FillChar(VScreen, 64000, 0);
      Burnin_Down_The_House;
      Asm
        MOV  AX,3
        INT  10h
      End;
    End.

[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]