#resize TRUE
#pragma option argc


// Включаем поддержку модов
#define __MODPLAYER__ TRUE


#include "soundsys\write.h--"    // Библа для вывода данных на экран
#include "soundsys\sb.h--"       // Библа для работы с Sound Blaster-ом
#include "soundsys\wave.h--"     // Библа для подгрузки семплов в формате WAV
#include "soundsys\modplay.h--"  // Библа для проигрывания MOD-модулей

#define SCREENSIZE 64000
#define MEMBLOCKSIZE SCREENSIZE/16
#define RAZSIZE 120
#define RAZSIZEB RAZSIZE+40
#define RAZSIZEA RAZSIZEB/8
#define RAZSIZEC RAZSIZEA*32
#define HODSIZE 2


byte ball[320] = FROM "ball.gfx";
byte line[16] = FROM "line.gfx";
byte font[3072] = FROM "busy.fnt";
byte texta = FROM "info.txt";
byte muz = FROM "dax.muz";


byte oldvek=0;
word massiv; //массив в котором создается днк
word bufer; //массив с которым работает программа во время инициализации

byte baaa,ba,bb,/*bc,bd,be,*/baa,bba,bab,bbb; // Свободные переменные
word wwa,wwb,wa,wb,wc,wd,waa,wab,/*wac,wad,*/wabb; // Свободные переменные
byte bum=0;
byte scrollb;
word scrollw;

byte music;

float canst0=0.0176;
float canst2=1.5;
float canst3=0.5;
float canst5=120;
float time=0;
long abx;//,aby=0;



void main()  //Начинаем прогу
{
FCREATE ( , , 0, "dax.mod");
wc=AX;
FOR (wa=0;wa<11662;wa++)
{
AX=muz[wa];
PUTC (AX,wc);
}
FCLOSE (,wc);

 // Есть параметры в коммандной строке ?
IF (PARAMCOUNT()>1)
{music=1;
GOTO L1;
}


 // Инициализация всего
 InitAll();

  // Подгружаем мод-файл

  IF (music==0);
{  LoadModFile("dax.mod");

  // Начинаем воспроизведение мод-модуля
  PlayModModule=TRUE;
}
L1:





 $Cli
 $MOV DX,21h
 $IN AL,DX
 oldvek=AL;

 $OR AL,11b
 $OUT DX,AL
 $Sti

        massiv=GETMEM(MEMBLOCKSIZE);
        bufer=GETMEM(MEMBLOCKSIZE);

clearb (63999,0,massiv); //отчистка



// пребрасываем шарики в bufer (8 штук)
ES=bufer;
FS=massiv;
wb=0;
FOR (ba=0;ba<8;ba++)
{
FOR (wa=0;wa<320;wa++)
{
AL=ball[wa];
ESBYTE[wb]=AL;
wb++;
 }
 }

//сдвигаем 7 шариков на 1бит в право начиная со второго (в wa уже 320)
FOR (ba=0;ba<7;ba++)
{
wc=wa;
FOR (wb=0;wb<2240/5;wb++)
{
$CLC;
CX=5;
loop(CX){
AL=ESBYTE[wa];
$RCR AL,1;
ESBYTE[wa]=AL;
wa+=1;
}
}
wa=wc+320;
}

//Создаем в massiv массив днк
wa=0;
for (ba=0;ba<80;ba++)
{
                asm{
                        fld time
                        fadd canst0
                        fst time
                        fmul canst2
                        fadd canst3
                        fsin
                        fmul canst5
                        fistp abx
                        fwait
}
baaa=abx;

bb=RAZSIZE-baaa;

baa=baaa/8;     //определяем знакоместо первого шарика
bab=baa*8;
bab=baaa-bab;   //определяем сдвиг первого шарика
bba=bb/8;
bbb=bba*8;
bbb=bb-bbb;
setline(baa,bba,wa);//Рисуем линию между шариками в массиве
setball(bba,bbb,wa);
setball(baa,bab,wa);//Рисуем первый шарик
wb=RAZSIZEB*4;
wa=wa+wb;
}

$PUSH wa;
wabb=wa;
FSBYTE[0]=0;
GOVGA16();
clearb (63999,0,bufer);
setrgbpalette(0,1,0,50);
setrgbpalette(63,255,255,150);
ES=0xa000;
GS=bufer;
waa=0;
$POP wabb;
waa=wabb;
scrollb=15;
scrollw=0;

//Основной цикл программы
MAINLOOP:

@WAITVSYNC();

SHOWDNK();
OUTTXT();

 $IN AL,60h                     // ; Keyboard reg
 $CMP AL,1                      // ; Check Escape
 $JZ END

$JMP MAINLOOP //Основной цикл программы завершен

END:
 $Cli
 $MOV DX,21h
 AL=oldvek;
 $OUT DX,AL
 $STI
        @SETVIDEOMODE(byte 0x3);
 // Деинициализация всего
IF (music=0) DeInitAll();

REMOVE("dax.mod");
} //End Main()


void clearb(word IX,IY,MX)
{
ES=MX;
AX=IY;
CX=IX;
DA1:
ESBYTE[CX]=AL;
$loop DA1;
}

void setrgbpalette(char color,r,g,b)
{
        CX=0x3C8;
        outp(color,CX);
        CX++;
        outp(r,CX);
        outp(g,CX);
        outp(b,CX);
}  //End


// Инициализация всего
InitAll()
{
 IF (!SbAutoDetect()){
music=1;
 }ELSE
 InitSb();
music=0;
 InitModSystem();
}



// Деинициализация всего
DeInitAll()
{
 WriteStr("\n\nДеинициализация SB... ");
  DeInitSb();
 WriteStr("OK");

 // Инициализируем мод-систему
 DeInitModSystem();
}










void setline(byte xf,xl, word gde)
word peremw;
byte peremb,peremba;

{
peremb=0;
xf+=3;
xl+=1;
                                IF (xf>xl)
                                {
peremba=xf;
xf=xl;
xl=peremba;
}

                                IF (xf<xl){


peremw=RAZSIZEB;

gde=gde+xf+peremw;

do{
peremw=gde;
FOR (peremba=0;peremba<16;peremba++)
{
AL=line[peremba];
FSBYTE[gde]=AL;
//FSBYTE[gde]=255;
gde=gde+RAZSIZEA;
peremb++;
}
gde=peremw+1;
xf++;
}while (xf!=xl);
}
}  //End

void setball(byte znak, zdvig, word gde)
word peremw,peremwa;
byte peremb,peremba;
{
gde=gde+znak;
peremwa=zdvig*320;

FOR (peremba=0;peremba<32;peremba++)
{
peremw=gde;
FOR (peremb=0;peremb<5;peremb++)
{
AL=ESBYTE[peremwa+160];
!AL;
$AND FSBYTE[gde],AL;
AL=ESBYTE[peremwa];
$OR FSBYTE[gde],AL;
peremwa++;
gde++;
}
gde=peremw+RAZSIZEA;
}
}  //End

void SHOWDNK()
{
wab=waa;
wb=0;
for (wd=0;wd<480;wd++)
{
IF (wb>30)
{
wwa=waa/RAZSIZEC;
wwb=wwa*RAZSIZEC;
wwb=wwb-waa;
IF (wwb==0)
{
wwa=RAZSIZEC*4;
waa=waa+wwa;
}
IF (waa>=wabb)
{waa=waa-wabb;
}
}
wc=wb;
FOR (bb=0;bb<RAZSIZEA;bb+=2)
{
AX=FSWORD[waa];
ESWORD[wb]=AX;
ESWORD[wb+60]=AX;
wb+=2;
waa+=2;
IF (waa>=wabb)
{waa=waa-wabb;
}
}
wb=wc+80;
}
waa=wab+RAZSIZEA+RAZSIZEA+RAZSIZEC;
bum+=1;
IF (bum==16)
{
bum=0;
waa+=RAZSIZEC*4;
}
IF (waa>=wabb)
{waa=waa-wabb;
}
}    //End showdnk()


: void GOVGA16 ()
{AH= 0;
AL=0x12;
$ INT 0x10
}





void OUTTXT()
word dax;

{
wa=20;
FOR (wd=0;wd<479;wd++)
{
FOR (wc=0;wc<20;wc++)
{
AX=ESWORD[wa+80];
ESWORD[wa]=AX;
wa+=2;
}
wa+=40;
}
scrollb++;
if (scrollb==36)
{scrollb=0;
wd=0;

FOR (ba=0;ba<20;ba++)
{
dax=texta[scrollw];
dax-=32;
dax=dax*32;
wc=wd;
scrollw+=1;
FOR (bb=0;bb<16;bb++)
{
AL=font[dax];
GSBYTE[wd]=AL;
dax+=1;
wd+=1;
AL=font[dax];
GSBYTE[wd]=AL;
dax+=1;
wd+=39;
}

wd=wc+2;
}
IF (texta[scrollw]==251)
{scrollw=0;}
ELSE{scrollw+=3;}
}
wa=scrollb*40;
FOR (wb=20;wb<60;wb++)
{
AL=GSBYTE[wa];
ESBYTE[wb+38320]=AL;
wa++;
}
}
