#use80386
#resize TRUE
#parsecommandline TRUE
#codesize
//#jumptomain SHORT
#pragma option de
#pragma option texe
#stack 2048
#define SCREENSIZE 64000
#define MEMBLOCKSIZE SCREENSIZE/16
#define SEEK_SET 0



#define PI2 3.14159265358979324*2
#define XPixels 50
#define YPixels 50




//byte ErrorMesg="Error loading Module file.\n";
byte MsgNotFound="Sound Blaster not found. Type GLUK2.EXE /N for no music.\n";
//word Scope[320];
//word RowOfs[256];



?include "SB.h--"
?include "MODLOAD.h--"
?include "MODPLAY.h--"




byte font[768] = FROM "amiga.fnt";
byte ppx[1959] = FROM "gluk2.pix";
byte muz[15156] = FROM "gluk2.muz";
byte text[3081] = FROM "gluk2.txt";

byte muza=1;
//float ya,xa=0;
//float dadad=0;
byte oldvek=0;


word zaderjka=670;
word sinmax;
//word sina=0;
//byte texo;
word texx,texb,texc,texd,texe,texf=0;
word tschet=320;
word atex,btex,ctex,texxa/*,texxb,texaa,texbb,texcc=0*/;
word va;//,vb,vc,vd,ve,vf;

word texts=255;

//word TEXA;
byte txc;
word ddx,ddy;
//long IYY;

//word prog,prog1;
//word x,y,
word IX,IY,MAX,MX,MY;
word DAX,/*DAXX,ss,*/zad;
long NX,NY;
int kuda;
//byte exit=0;
word setkascr;
float cinst0=0.04;
//float cinst1=0.1;
float cinst2=1.1;
float cinst3=1.7;
//float cinst4=0;
float cinst5=160;

float canst0=0.001;
float canst1=0.2;
float canst2=0.2;
float canst3=0.2;
float canst4=220;
float canst5=960;



word textt;
word screen;
word pics;
word sqr;
long bbx,bby;


long abx,aby=0;

float time=0;

word sin[100]=0;

float const0=0.033;
float const1=0.8;
float const2=1.1;
float const3=1.5;
float const4=90;
float const5=120;
void setrgbpalette(char color,r,g,b);



void main()

{


        IF(@PARAMCOUNT()!=0)
        {muza=0;
        $jmp short EX;
        }

        CSWORD[#SegDS]=DS;
        DetectSb();             //Detect the SB Addr,


 $Cli                           // ; FuCK interrupts
 $MOV DX,21h                    // ; Interrupt mask reg!
 $IN AL,DX
 oldvek=AL;

 $OR AL,11b                     // ; Turn off keyboard and timer interrupt
 $OUT DX,AL
 $Sti



FCREATE ( , , 0, "gluk2.mod");
IX=AX;
FOR (IY=0;IY<15156;IY++)
{
AX=muz[IY];
PUTC (AX,IX);

}
FCLOSE (,IX);
        //EXIT(byte 1);
        LoadModule("gluk2.mod");

        MixSpeed=22000;
        SbInit();


EX:


MAX=zad=100;

ddx=ddy=kuda=NX=NY=atex=0;



        screen=GETMEM(MEMBLOCKSIZE);
        textt=GETMEM(MEMBLOCKSIZE);
        pics=GETMEM(MEMBLOCKSIZE);
        setkascr=GETMEM(MEMBLOCKSIZE);
        sqr=GETMEM(MEMBLOCKSIZE*2);
        @SETVIDEOMODE(byte 0x13);


clearb (63999,0,textt);
clearb (63999,0,pics);



IX=320*8;

ES=pics;


FOR (IY=0;IY<1959;IY++)
{
AL=ppx[IY];

CX=8;
loop(CX){
$RCL AL,1;
$jc AMETKA1;
$push AX;
ESBYTE[IX]=255;
$pop AX;
AMETKA1:
IX+=1;
}
}

        initsqr();
        blurpics();
        setcolortable();


texf=0;
WHILE (abx!=160)
{

                asm{
                        fld time
                        fadd cinst0
                        fst time
                        fmul cinst2
                        fadd cinst3
                        fsin
                        fmul cinst5
                        fistp abx
                        }

}
WHILE (abx>=-159)
{

                asm{
                        fld time
                        fadd cinst0
                        fst time
                        fmul cinst2
                        fadd cinst3
                        fsin
                        fmul cinst5
                        fistp abx
                        }

sin[texf]=abx+160;
texf+=1;
}
sinmax=texf;




DAAAX:


                asm{
                        fld time
                        fadd const0
                        fst time
                        fmul const2
                        fadd const3
                        fsin
                        fmul const5
                        fistp bbx
                        fwait
                }
                bbx+=160;

                asm{
                        fld time
                        fmul const1
                        fadd const2
                        fcos
                        fmul const4
                        fistp bby
                        fwait
                }
                bby+=100;



                asm{
                        fld time
                        fadd canst0
                        fst time
                        fmul canst2
                        fadd canst3
                        fsin
                        fmul canst5
                        fistp abx
                        }
                        asm
                        {
                        fwait
                        fld time
                        fmul canst1
                        fadd canst2
                        fcos
                        fmul canst4
                        fistp aby
                        fwait
                }

NX=abx;
NY=aby;


IF (muza==1){
                SbPoll();
            }
                copypicsvirtual();
                radialblurscreen();
                blurscreen();


                setka();
                copyvirtualscreen();
                textsc();
                setkaout();



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

        $JMP DAAAX
        SbDone();









DAAAX2:

 $MOV DX,21h
 AL=oldvek;
 $OUT DX,AL                   //   ; Trust me, the user will like this, hehe :)
 $STI

IF (muza==1){

        FreeModule();
}

REMOVE("gluk2.mod");


        @SETVIDEOMODE(byte 0x3);
}



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

}





void setka()
{




MY=MX=MAX/2;
NX+=ddx;
NY+=ddy;



WHILE (NX>MAX)NX=NX-MAX;
WHILE (NY>MAX)NY=NY-MAX;
WHILE (NY<0)NY=NY+MAX;
WHILE (NX<0)NX=NX+MAX;

DI=0;
ES=setkascr;
IY=NY;
do{
IX=NX;


FOR(DAX=0;DAX<320;DAX++){

IF (IY<MY){
IF (IX<MX)ESBYTE[DI]=255;
ELSE ESBYTE[DI]=0;
}
ELSE{
IF (IX<MX)ESBYTE[DI]=0;
ELSE ESBYTE[DI]=255;

}



IX++;
IF (IX>=MAX)
{IX=0;}


DI=DI+1;
}
IY++;
IF (IY>=MAX)
{IY=0;}


}while(DI<32000);

        copyfard(ES,32000,ES,0,8000);

}




void setkaout()
{
        @WAITVSYNC();
        copyfard(0xA000,0,setkascr,0,16000);

}




void blurpics()
{
        ES=pics;
        FOR(DI=320;DI<20000-320-320;){
                AX=ESBYTE[DI-320]+ESBYTE[DI-1]+ESBYTE[DI+1]+ESBYTE[DI+320]>>3;
                $stosb
        }
}

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






void setcolortable()
{
        FOR(CX=0;CX<=255;CX++){
                AL=255-CL/2;
                setrgbpalette(CL,AL,AL,AL);

        }


        FOR(CX=128;CX<=255;CX++){
AL=383-CL/2;
                setrgbpalette(CL,200,AL,AL);
}
setrgbpalette(255,200,255,255);
setrgbpalette(0,250,255,245);



//setrgbpalette(241,10,150,110);
setrgbpalette(241,20,145,155);
//setrgbpalette(241,140,5,45);
setrgbpalette(242,155,255,255);

setrgbpalette(243,0,155,0);
setrgbpalette(244,145,245,245);


setrgbpalette(245,140,5,45);
setrgbpalette(246,240,245,255);

setrgbpalette(247,20,155,155); //3
setrgbpalette(248,240,55,55);

setrgbpalette(249,140,155,155);
setrgbpalette(250,140,55,55);

setrgbpalette(251,120,135,135);
setrgbpalette(252,40,55,55);

setrgbpalette(253,15,225,20);
setrgbpalette(254,255,245,255);

}

void copypicsvirtual()
{
        ES=screen;
        $push DS
        DS=pics;
        SI=0;
        DI=0;
        CX=16000;
        $rep $movsd
        $pop DS
}

void radialblurscreen()
int x,y,vx,p1;
int t;
{
        ES=screen;
        FS=sqr;
        GS=64000/16+sqr;
        t=0;
        AX=bby-1<<6;
        BX=AX<<2;
        DI=AX+BX+bbx-1;
        FOR(y=bby-1;y>=0;y--){
                FOR(x=bbx-1;x>=0;x--){
                        p1=ESBYTE[DI];
                        SI=t;
                        vx=GSBYTE[SI];  //*((char*)(t+64000));
                        AX=FSBYTE[SI];  //*((char*)(t));
                        AX<<=6;
                        BX=AX<<2;
                        AX=ESBYTE[DI+vx+AX+BX]; //*((char*)(s+vx+(vy<<8)+(vy<<6)));
                        ESBYTE[DI]=word AX+p1>>1; //*((char*)(s))=(p1+p2)>>1;
                        DI--;
                        t++;
                }
                DI=DI-320+bbx;
                t+=320-bbx;
        }
        AX=bby-1<<6;
        BX=AX<<2;
        DI=AX+BX+bbx;
        t=0;
        FOR(y=bby-1;y>=0;y--){
                FOR(x=bbx;x<320;x++){
                                p1=ESBYTE[DI];  //p1=*((char*)(s));
                                SI=t;
                                vx=GSBYTE[SI];  //*((char*)(t+64000));
                                AX=FSBYTE[SI];  //*((char*)(t));
                                AX<<=6;
                                BX=AX<<2;
                                AX=ESBYTE[DI-vx+AX+BX]; //*((char*)(s-vx+(vy<<8)+(vy<<6)));
                                ESBYTE[DI]=word AX+p1>>1; //*((char*)(s))=(p1+p2)>>1;
                                DI++;
                                t++;
                        }
                DI=DI-640+bbx;
                t+=bbx;
        }
        AX=bby<<6;
        BX=AX<<2;
        DI=AX+BX+bbx-1;
        t=0;    //t=tn;
        FOR(y=bby;y<130;y++){
                FOR(x=bbx-1;x>=0;x--){
                                p1=ESBYTE[DI];  //p1=*((char*)(s));
                                SI=t;
                                vx=GSBYTE[SI];  //*((char*)(t+64000));
                                AX=FSBYTE[SI];  //*((char*)(t));
                                AX<<=6;
                                BX=AX<<2;
                                AX=ESBYTE[DI+vx-AX-BX]; //*((char*)(s+vx-(vy<<8)-(vy<<6)));
                                ESBYTE[DI]=word AX+p1>>1; //*((char*)(s))=(p1+p2)>>1;
                                DI--;
                                t++;
                        }
                DI=DI+320+bbx;
                t+=320-bbx;
        }
        AX=bby<<6;
        BX=AX<<2;
        DI=AX+BX+bbx;
        t=0;    //t=tn;
        FOR(y=bby;y<100;y++){
                FOR(x=bbx;x<320;x++){
                        p1=ESBYTE[DI];  //p1=*((char*)(s));
                        SI=t;
                        vx=GSBYTE[SI];  //*((char*)(t+64000));
                        AX=FSBYTE[SI];  //*((char*)(t));
                        AX<<=6;
                        BX=AX<<2;
                        AX=ESBYTE[DI-vx-AX-BX]; //*((char*)(s-vx-(vy<<8)-(vy<<6)));
                        ESBYTE[DI]=word AX+p1>>1; //*((char*)(s))=(p1+p2)>>1;
                        DI++;
                        t++;
                }
                DI+=bbx;
                t+=bbx;
        }
}

void blurscreen()
{
        ES=screen;
        FOR(DI=320;DI<60000-320-328;){
                AX=ESBYTE[DI-320]+ESBYTE[DI-1]+ESBYTE[DI+1]+ESBYTE[DI+320]>>2;
                $stosb
        }
}








void copyvirtualscreen()
{
        ES=setkascr;
        $push DS
        DS=screen;
//        SI=0;
//        DI=0;
//        CX=9000;
FOR (DI=0;DI<33000;DI++)
{
AX=DSBYTE[DI];
CX=ESBYTE[DI];
IF (CX==0){
ESBYTE[DI]=AX;
}
ELSE
{
AX+=128;
ESBYTE[DI]=AX;
}
}

        $pop DS



}

void textwrite()
{
        ES=textt;
        texxa=tschet;

for (ctex=0;ctex<7;ctex++)
{
        texx=texxa;

txc=text[atex];
IF (AL==37)
{atex=0;
txc=text[atex];
}
txc-=48;

texts=256;
IF (txc==4)||(txc==7)||(txc==2)texts=255;




txc=txc*2+241;
        atex+=1;
        texe=atex;
        btex=atex+40;




FOR (texe=texe;texe<btex;texe++)
{
texc=text[texe]*8-texts;
//texc=texc*8;
//texc-=texts;

texd=texx;
           FOR (texb=0;texb<8;texb++)
           {
AL=font[texc];


CX=8;
loop(CX){

$RCL AL,1;
IF(CARRYFLAG){
$push AX;
ESBYTE[texd]=txc;
$pop AX;
}
ELSE{
ESBYTE[texd]=0;
}
texd+=1;
}

texc+=1;
texd=texd+640-8;
           }
texx+=8;
}

        texxa+=5120;
atex+=43;
}
}









void textsc()
{
zaderjka+=1;
IF (zaderjka==800)
{
tschet+=320;//gde v bufer
IF (tschet==640)tschet=0;
textwrite();


zaderjka=0;
}

texf=zaderjka;
FOR (va=0;va<7;va++)
{
IF (texf>sinmax)texf=sinmax;
CX=sin[texf];
CX=ABS(tschet-CX);
textout(CX,va);
texf+=1;
}
}







void textout(word TEXA,texd)
{

        ES=setkascr;
        $push DS
        DS=textt;

        texb=texd*320*16;
        TEXA+=texb;
        texb+=25600;


FOR (texx=0;texx<7;texx++)

{FOR (DI=0;DI<320;DI++)
{
AX=DSBYTE[TEXA];
IF (AX!=0){

SI=texb;
ESBYTE[SI]=AX;
ESBYTE[SI+320]=AX;
IF(DI<318)
{
AX+=1;
ESBYTE[SI+2]=AX;
ESBYTE[SI+322]=AX;
}

}
TEXA+=1;
texb+=1;
}
texb+=320;
TEXA+=320;
}



    $pop DS
}















void DetectSb()
{
        BX=0x210;
        do{
                DX=BX+6;
                outp(1);
                inp();
                inp();
                inp();
                inp();
                outp(0);
                DL+=8;
                CX=100;
                loop(CX){
                        loop(CX){
                                inp();
                                AL|=AL;
                                IF(MINUSFLAG)GOTO GETID;
                        }
                        GOTO NEXTPORT;
GETID:
                        DL-=4;
                        inp();
                        IF(AL==0xAA)GOTO FOUND;
                        DL+=4;
                }
NEXTPORT:
                BX+=0x10;
        }while(BX<=0x260);
        $jmp near FAIL;
FOUND:
        SbAddr=BX;
        $cli
        BL=inp(0x21);
        outp(0b11111111,0x21);
        ES=0;
        $push ESDWORD[0x28]     //irq2
        $push ESDWORD[0x2c] // irq3
        $push ESDWORD[0x34]     // irq5
        $push ESDWORD[0x3C]     // irq7
        ESWORD[0x28]=#TrapIrq2;
        ESWORD[0x2A]=CS;
        ESWORD[0x2C]=#TrapIrq3;
        ESWORD[0x2E]=CS;
        ESWORD[0x34]=#TrapIrq5;
        ESWORD[0x36]=CS;
        ESWORD[0x3C]=#TrapIrq7;
        ESWORD[0x3E]=CS;
        AL=BL&0b01010011;       // enable IRQs 2,3,5,7.
        outp(AL,0x21);
        $sti
        SbIrq=0;
        DX=SbAddr+12;
        do{
                inp();
                AL|=AL;
        }while(MINUSFLAG);
        outp(0xF2);
        CX=0;
        loop(CX){
                IF(SbIrq!=0)BREAK;
        }
        outp(BL,0x21);
        $cli
        ES=0;
        $pop ESDWORD[0x3c]
        $pop ESDWORD[0x34]
        $pop ESDWORD[0x2C]
        $pop ESDWORD[0x28]
        $cli
        IF(SbIrq==0){
FAIL:
                WRITESTR(#MsgNotFound);
                EXIT(byte 0);
        }
}

void TrapIrq2()
inline
{
        $push AX
        AX=2;
        GOTO TrapIrq;
}

void TrapIrq3()
inline
{
        $push AX
        AX=3;
        GOTO TrapIrq;
}

void TrapIrq5()
inline
{
        $push AX
        AX=5;
        GOTO TrapIrq;
}

void TrapIrq7()
inline
{
        $push AX
        AX=7;
//      GOTO TrapIrq;
}

void /*interrupt*/ TrapIrq()
inline
{
        $push    DX,DS
        DX=CSWORD[#SegDS];
        DS=DX;
        SbIrq=AX;
        DX=SbAddr+14;
        inp();
        @EOI();
        $pop     DS,DX,AX
        $iret
}









void initsqr()
int x,y;
dword n;
{
        ES=sqr;
        GS=64000/16+sqr;
        FOR(x=0;x<320;x++){
                FOR(y=0;y<200;y++){
                        AX=y*y;
                        BX><AX;
                        n=x*x+BX;
                        asm{
                                fild n
                                fsqrt
                                fistp n
                                fwait
                        }
                        n=n/8+1;//                      n=(sqrt(x*x+y*y)/8)+1;
                        SI=y*320+x;
                        AX=int x/n;
                        GSBYTE[SI]=AL;
                        AX=int y/n;
                        ESBYTE[SI]=AL;
                }
        }
}

