?resize FALSE
?use80386
?codesize
?jumptomain NONE

?define PALSIZE 256*3
?define XSIZE 160
?define YSIZE 100
?define WATERTABLESIZE XSIZE*YSIZE*2  // must be divisible by 16!
?define WATERTABLEPARAGRAPHSIZE WATERTABLESIZE/16
?define DAMPEN 3

byte palette[PALSIZE];
word watertable1,watertable2;

main()
{
  AX=0x13;
  $int 0x10
  outport(0x4309,0x3D4);
  BX=0;
  DI=#palette;
  ES=DS;
  do{
    IF(BL<128){
      AL=127-BL>>1;
      AH=AL;
    }
    ELSE AX=0;
    $STOSW
    CL=BL;
    CL>>=1;
    AL=127-CL>>1;
    $STOSB
    BL++;
  }while(NOTZEROFLAG);
  @SETVGADAC(0,,PALSIZE,,,#palette[3]);
  do_water();
  AX=0x3;
  $int 0x10
}

struct splash
{
  int XS;
  int YS;
  int XP;
  int YP;
}small={5,0,10<<3,5<<3}, big={-3,0,38<<3,15<<3};

void CALCADR()
{
  IF(DSWORD[BX+4]>XSIZE*4)DSWORD[BX]--;
  ELSE DSWORD[BX]++;
  IF(DSWORD[BX+6]>YSIZE*4)DSWORD[BX+2]--;
  ELSE DSWORD[BX+2]++;
  DSWORD[BX+4]+=DSWORD[BX];
  DSWORD[BX+6]+=DSWORD[BX+2];
  DI=DSWORD[BX+4]>>3;
  AX=DSWORD[BX+6]>>3*160;
  DI+=AX;
  DI+=DI;
}

void ShowWaterASM()
{
  $PUSH DS
  DS=watertable1;
  ES=0xA000;
  DI=0;
  BH=100;
  loop(BH){
    BL=160;
    loop(BL){
      AX=DSWORD[DI]-DSWORD[DI-2];
      $SAR AX,3
      AX+=100;
      AH=AL;
      $STOSW
    }
  }
  $POP DS
}

void CalcWaterEffect()
{
  $PUSH DS
  ES=watertable2;
  DS=watertable1;
  DI=161*2;
  DH=98;
  loop(DH){
    DL=158;
    loop(DL){
      AX=DSWORD[DI-320]+DSWORD[DI-2]+DSWORD[DI+2]+DSWORD[DI+320];
      $SAR AX,1
      AX-=ESWORD[DI];
      BX=AX;
      $SAR BX,DAMPEN
      AX-=BX;
      $STOSW;
    }
    DI+=4;
  }
  $POP DS
  watertable2><watertable1;
}

void do_water()
{
  $PUSH DS
  $POP AX
	AH+=0x10;
  watertable1=AX;
  ES=AX;
  watertable2=AX+WATERTABLEPARAGRAPHSIZE;
  DI=0;
  CX=WATERTABLESIZE;
  AX=0;
  $REPZ
  $STOSW  // initialize wt1 and wt2
  for(SI=0;;SI+=2){
    @WAITVSYNC();
    ShowWaterASM();
    CalcWaterEffect();
    CALCADR(,#small);
    ES=watertable1;
    AX=900;
    $push DI
    $STOSW
    $STOSW
    $pop DI
    ES=watertable2;
    AX=AX/2;
    $STOSW
    $STOSW
    IF(SI&256){
      CALCADR(,#big);
      CX=5;
      loop(CX){
        BX=5;
        loop(BX){
          ES=watertable1;
          AX=900;
          ESWORD[DI]=AX;
          ES=watertable2;
          AX=AX/2;
          $STOSW
        }
        DI+=310;
      }
    }
    AH=1;
    $int 0x16
    IF(NOTZEROFLAG)BREAK;
  }
  @BIOSREADKEY();
}
