#pragma option d32
#stack 60000
#parsecommandline TRUE
#pragma option stub=c:\c--\zrdx.exe

#define MemSize 1024*1024*4 //bytes

#include "variabl.inc"
#include "fixed.h--"
#include "keyboard.h--"
#include "write.h--"
#include "other.h--"
#include "dpmi.h--"
#include "file.h--"
#include "matrix.h--"
#include "mouse.h--"

#include "pcx.h--"
#include "3ds.h--"

#include "actions.h--"
#include "video.h--"
#include "3d.h--"
#include "font.h--"

main()
 dword numverts,numfaces,numtvertex;
 byte actions=TRUE;
 long objnum=0;
 dword i,ii;
 word fps,ffps;
 byte oldsec;
 word key;
{
 //Инициализация фпу-шки
 $finit

 IF (byte PARAMCOUNT()<1) return;

 //Randomize();

 //Установка видеорежима 320х200х256 цветов
 AX=13h; $int 10h

 //Создание нового сегмента размером 4Gbytes с начальным смещением 0
 IF (byte NewSegment4GB()==FALSE){
    WriteStr("\nError: 1"); return;
 }

 //Теперь ES указывает на сегмент размером в 4Gbytes и начальным смещением 0
 ES=BaseSel;
 //Теперь GS указывает на сегмент размером в 4Gbytes
 GS=TextureSel;

 //Глобальное выделение памяти
 MemOffs=GetDpmiMem(dword MemSize);
 IF (dword MemOffs==FALSE){
    WriteStr("\nError: 2"); return;
 }
 $push SI,DI $pop MemHandle;

 VideoBuf+=MemOffs;
// VideoBuf=0A0000h;  //Директом на экран
 SortBuf+=MemOffs;
 TextureBuf+=MemOffs;
 StatusMatrixBuf+=MemOffs;
 ModelsMemPointer+=MemOffs;
 ObjectsSxSyMemPointer+=MemOffs;
 ObjectsXYZMemPointer+=MemOffs;

 //Инициализация мыши
 MouseInit();

 //Чтение текстуры и установка палитры
 LoadPCXFile(dword TexturePCXFile, dword SortBuf, dword TextureBuf);
 SetVgaPalette(word 1,word 255,dword #PCX_palette+1+3);

 TextureWidth=PCX.xmax+1;
 TextureHeight=PCX.ymax+1;

 //Тут начились наши грязные дела
 ii=PARAMCOUNT();
 for (i=0; i<ii; i++){
  WriteStr(" Loading object #"); WriteDWord(i); WriteStr(" \"");
  WriteStr(PARAMSTR(i)); WriteStr("\"");
  Load3dsFile(dword PARAMSTR(i),dword i);
  tmp=i*1000;
  $fild tmp
  $fstp ftmp
  CreateObject(dword i, dword i, float 0, float 0, float ftmp, float 0, float 0, float 0);
  WriteStr("\n");
 }
 WriteStr("\nAll done............");

 fps=0;ffps=0;
 ClearVideoBuf();

/* CreateObject(dword NumObjects, dword 0, float 0, float 0, float 0);
 CreateObject(dword NumObjects, dword 0, float 0, float 0, float 0, float 0, float 0, float 0);
 CreateObject(dword NumObjects, dword 0, float 0, float 0, float 0, float 0, float 0, float 0);
 CreateObject(dword NumObjects, dword 0, float 0, float 0, float 0, float 0, float 0, float 0);
 CreateObject(dword NumObjects, dword 0, float 0, float 0, float 0, float 0, float 0, float 0);*/

 //Инициализируем камеру
// Sp = (0,0,dist)
// Sq = (xSize/2,0,0)
// Sr = (0,ySize/2,0)
 Camera.px=0; Camera.py=0; Camera.pz=dist;
 Camera.qx=HalfSizeX; Camera.qy=0; Camera.qz=0;
 Camera.rx=0; Camera.ry=HalfSizeY; Camera.rz=0;
 Camera.sx=0; Camera.sy=0; Camera.sz=-dist;
 Camera.RotateOX=0; Camera.RotateOY=0; Camera.RotateOZ=0;


 loop(){

    AH=2Ch;$int 21h
    IF (DH==oldsec)ffps++;ELSE{oldsec=DH;fps=ffps;ffps=0;}

    // Обработка клавы
    AH=1; $int 16h
    key=0;
    if (NOTZEROFLAG){
       key=ReadKey();

       IF (key==k_esc) break;
       IF (key==k_home) Object[objnum].z-=100;
       IF (key==k_end) Object[objnum].z+=100;
       IF (key==k_delete) Object[objnum].rz+=0.017453292519943296*2;
       IF (key==k_pagedown) Object[objnum].rz-=0.017453292519943296*2;
       IF (key==k_a) objnum++; IF (objnum==NumObjects) objnum=0;
       IF (key==k_q) objnum--; IF (objnum<0) objnum=NumObjects-1;
       IF (key==k_space) actions=1-actions;

       AH=2;$int 16h
       if (AL&3!=0){ // Если нажата shift
           IF (key==k_left) Object[objnum].ry-=0.017453292519943296*2;
           IF (key==k_right) Object[objnum].ry+=0.017453292519943296*2;
           IF (key==k_up) Object[objnum].rx-=0.017453292519943296*2;
           IF (key==k_down) Object[objnum].rx+=0.017453292519943296*2;
          }else{
           IF (key==k_left) Object[objnum].x-=10;
           IF (key==k_right) Object[objnum].x+=10;
           IF (key==k_up) Object[objnum].y+=10;
           IF (key==k_down) Object[objnum].y-=10;
          }
    }
    IF (byte actions){
//       ScaleModel(dword objnum, float 1,float 1,float 1);
//       MoveModel(dword objnum, float 0, float 0, float 0);
//       RotateModelOX(dword objnum, float 0.017453292519943296*3);
//       RotateModelOY(dword objnum, float 0.017453292519943296*2);
//       RotateModelOZ(dword objnum, float 0.017453292519943296*1.7);
         Object[objnum].rx+=0.017453292519943296;
         Object[objnum].ry+=0.017453292519943296;
         Object[objnum].rz+=0.017453292519943296;
    }

    MouseRotateObject(dword objnum);

    //Создаем матрицы статуса для всех объектов
    CreateObjectsStatusMatrix();

    FOR (i=0; i<NumObjects; i++) ProcessModelDots(dword i);

    //Спроецируем координаты точек объектов на экран
    ProectObjectDots();

    ZSortPoligons();
    RefreshObjects();

    WriteWordFont2(word 5,word 5,word fps);

    WriteWordFont2(word 5,word 15,word NumberVisibleFaces);

    WriteStrFont2(word 5, word 55, dword "Object(0) :");
    ESI=Object[0].OffsXYZ; $fld ESFLOAT[ESI+8] $fistp tmp WriteLongFont2(word 55, word 55, tmp);

    WriteStrFont2(word 5, word 25, dword "Camera.sx :"); $fld Camera.sx $fistp tmp WriteLongFont2(word 55, word 25, tmp);
    WriteStrFont2(word 5, word 35, dword "Camera.sy :"); $fld Camera.sy $fistp tmp WriteLongFont2(word 55, word 35, tmp);
    WriteStrFont2(word 5, word 45, dword "Camera.sz :"); $fld Camera.sz $fistp tmp WriteLongFont2(word 55, word 45, tmp);

    //Вывод видеобуфера на экран
//    WaitRetrace();
    PutVideoBuf();
    ClearVideoBuf();
 }

 //Очистка клавогого буфера
 loop(){
   AH=1; $int 16h
   IF (ZEROFLAG) BREAK;
   AH=0; $int 16h
 }

 //Текст мод
 AX=3; $int 10h

 //Освобождение выделенной памяти
 IF (byte FreeDpmiMem(dword MemHandle)==FALSE){
     WriteStr("\nError: 3"); return;
 }
 for (i=0; i<NumObjects; i++){
     modelnum=Object[i].ModelNum;
     WriteStr("\n\nObject: '");
     WriteDWord(dword i);
     WriteStr("'\nFaces         : ");
     WriteLong(long Model[modelnum].NumFaces);
     WriteStr("\nVertex        : ");
     WriteLong(long Model[modelnum].NumVerts);
     WriteStr("\nTexture Vertex: ");
     WriteLong(long Model[modelnum].NumTVerts);
 }
 WriteStr("\n\n---------------------");
 WriteStr("\nTotal Objects : "); WriteDWord(NumObjects);
 FOR (numverts=0,numfaces=0,numtvertex=0,i=0; i<NumObjects; i++){
     modelnum=Object[i].ModelNum;
     numverts+=Model[modelnum].NumVerts;
     numfaces+=Model[modelnum].NumFaces;
     numtvertex+=Model[modelnum].NumTVerts;
 }
 WriteStr("\nTotal Faces   : "); WriteDWord(numfaces);
 WriteStr("\nTotal Vertexs : "); WriteDWord(numverts);
 WriteStr("\nTotal TVertexs: "); WriteDWord(numtvertex);
 WriteStr("\nUsed memory   : "); WriteDWord(ModelsMemPointer-MemOffs);
 WriteStr("\n\n(c)2000 Din (2:5055/141.11) & Wega (2:5055/141.10)");
}
