Subversion Repositories Kolibri OS

Rev

Rev 8919 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <kolibri.h>
  2. #include <kos_heap.h>
  3. #include <kos_file.h>
  4. #include <kos_unpack.h>
  5. #include <load_lib.h>
  6. #include <l_proc_lib.h>
  7. #include <l_tinygl.h>
  8. #include <l_box_lib.h>
  9.  
  10. using namespace Kolibri;
  11.  
  12. const char header[] = "Blocks";
  13. char library_path[2048];
  14.  
  15. OpenDialog_data ofd;
  16. unsigned char procinfo[1024];
  17. char plugin_path[4096], openfile_path[4096], filename_area[256];
  18. od_filter filter1 = { 7, "BJS\0\0" };
  19.  
  20. namespace Kolibri{
  21.         char CurrentDirectoryPath[2048];
  22. }
  23.  
  24. struct BlockList{
  25.         unsigned char* name;
  26.         long int id_l, p_cou;
  27.         float* vert_d;
  28.         float* norm_d;
  29. };
  30.  
  31. BlockList* b_list = 0;
  32. long int b_count;
  33.  
  34. unsigned char* b_data = 0;
  35. unsigned char* f_data = 0;
  36.  
  37. struct ColorList{
  38.         unsigned char* name;
  39.         long int color;
  40. };
  41.  
  42. const long C_COUNT_MAX = 32;
  43. const long TOOLBAR_H = 29;
  44. ColorList c_list[C_COUNT_MAX];
  45. long c_count = 0;
  46.  
  47. struct ModelList{
  48.         char* name;
  49.         long int color, t_cr;
  50.         float x,y,z, r_x,r_y,r_z;
  51.         unsigned long level;
  52.         long int id_l;
  53. };
  54.  
  55. ModelList* model_list = 0;
  56. long int m_count;
  57.  
  58. TinyGLContext ctx1;
  59. float angle_x = 135.0, angle_y = 0.0, angle_z = 0.0, delt_size = 3.0,
  60.         scale_o = 0.1, trans_z = 0.0;
  61. double rat_h = 1.0;
  62. bool mouse_drag = false;
  63. short mouse_x, mouse_y;
  64. float angle_dwm, //~ wnd_w/180 - прибавление углов поворота сцены при вращении мышей
  65.         angle_dhm;   //~ wnd_h/180
  66.  
  67. float light_position[] = {-30.0, 80.0, -50.0, 1.0}; //Расположение источника [0][1][2]
  68.         //[3] = (0.0 - бесконечно удаленный источник, 1.0 - источник света на определенном расстоянии)
  69. float light_dir[] = {0.0,0.0,0.0}; //направление лампы
  70.  
  71. float mat_specular[] = {0.3, 0.3, 0.3, 1.0}; //Цвет блика
  72. float mat_shininess = 3.0; //Размер блика (обратная пропорция)
  73. float white_light[] = {1.0, 1.0, 1.0, 1.0}; //Цвет и интенсивность освещения, генерируемого источником
  74. float lmodel_ambient[] = {0.3, 0.3, 0.3, 1.0}; //Параметры фонового освещения
  75.  
  76. char str1[] = "Show active level";
  77. check_box check1 = { {16,310,20,4}, 8, 0xffffff, 0x808080, 0xffffff, str1, ch_flag_middle };
  78. scrollbar sb_tcr = { 200,100,19,4, 16, 1, 20,1,0, 0x808080, 0xffffff, 0x0};
  79.  
  80. void SetLight()
  81. {
  82.         glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  83.         glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir);
  84.  
  85.         glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
  86.         glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
  87.  
  88.         glEnable(GL_COLOR_MATERIAL);
  89.         glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
  90.         glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
  91.         glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
  92.         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  93.  
  94.         glEnable(GL_LIGHTING);
  95.         glEnable(GL_LIGHT0);
  96. }
  97.  
  98. long list_get_id(char* name)
  99. {
  100.         long i;
  101.         long n = strchr(name, '\'')-name;
  102.         if(n) name[n] = 0;
  103.         for(i=0;i<b_count;i++){
  104.                 if(!strcmp(name,b_list[i].name)) return b_list[i].id_l;
  105.         }
  106.         return b_list[0].id_l; //not found
  107. }
  108.  
  109. long color_get_id(char* name)
  110. {
  111.         long i;
  112.         char* buf;
  113.         for(i=0;i<c_count;i++){
  114.                 buf = strchr(c_list[i].name, '=');
  115.                 if(buf){
  116.                         buf[0]=0;
  117.                         while(buf>c_list[i].name && buf[-1]==' '){
  118.                                 buf--; buf[0]=0;
  119.                         };
  120.                 }
  121.                 while(name[0]==' '){
  122.                         name++;
  123.                 };
  124.                 if(!strcmp(name,c_list[i].name)) return i;
  125.         }
  126.         return -1; //not found
  127. }
  128.  
  129. void draw_3d()
  130. {
  131.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //очистим буфер цвета и глубины
  132.         glPushMatrix();
  133.  
  134.         if(b_list){
  135.                 SetLight();
  136.                 glTranslatef(0.0,0.0,0.5);
  137.                 glScalef(scale_o*rat_h,-scale_o,scale_o/4.0); // z/2.0
  138.                 glTranslatef(0.0, trans_z, 0.0);
  139.                 glRotatef(angle_x,1.0,0.0,0.0);
  140.                 glRotatef(angle_y,0.0,1.0,0.0);
  141.                 glRotatef(angle_z,0.0,0.0,1.0);
  142.  
  143.                 long i;
  144.                 if(model_list){
  145.                         unsigned long pu_cou=0, pu_lvl=0;
  146.                         for(i=0;i<m_count;i++){
  147.                                 while(model_list[i].level<=pu_lvl && pu_cou){
  148.                                         pu_cou--;
  149.                                         pu_lvl--;
  150.                                         glPopMatrix();
  151.                                 };
  152.                                 pu_lvl=model_list[i].level;
  153.                                 pu_cou++;
  154.                                 glPushMatrix();
  155.                                 glTranslatef(model_list[i].x, model_list[i].y, model_list[i].z);
  156.                                 glRotatef(model_list[i].r_x, 1.0,0.0,0.0);
  157.                                 glRotatef(model_list[i].r_y, 0.0,1.0,0.0);
  158.                                 glRotatef(model_list[i].r_z, 0.0,0.0,1.0);
  159.                                 if((check1.flags&ch_flag_en && model_list[i].t_cr==sb_tcr.position)||
  160.                                 (!(check1.flags&ch_flag_en) && model_list[i].t_cr<=sb_tcr.position)){
  161.                                 glColor3ub((model_list[i].color>>16)&255,
  162.                                         (model_list[i].color>> 8)&255,
  163.                                         model_list[i].color&255);
  164.                                 glCallList(model_list[i].id_l);
  165.                                 }
  166.                         }
  167.                         while(pu_cou){
  168.                                 pu_cou--;
  169.                                 glPopMatrix();
  170.                         };
  171.                 }
  172.                 else{
  173.                         glColor3f(1.0, 1.0, 0.0);
  174.                         glCallList(b_list[0].id_l);
  175.                 }
  176.         }
  177.  
  178.         glPopMatrix();
  179. }
  180.  
  181. void compile_list(BlockList *list){
  182.         long int i;
  183.         list->id_l = glGenLists(1);
  184.         if(list->id_l<1) return; //not found
  185.         glNewList(list->id_l, GL_COMPILE);
  186.                 glBegin(GL_TRIANGLES);
  187.                 for(i=0;i<list->p_cou;i++){
  188.                         glNormal3fv((float*)(list->norm_d+i*3));
  189.                         glVertex3fv((float*)(list->vert_d+i*3));
  190.                 }
  191.                 glEnd();
  192.         glEndList();
  193. }
  194.  
  195. bool init_block(){
  196.         FileInfoBlock* file;
  197.         unsigned long int k;
  198.  
  199.         k = strlen(CurrentDirectoryPath);
  200.         while(CurrentDirectoryPath[k] != '\\' && CurrentDirectoryPath[k] != '/' && k) {k--;};
  201.         memcpy(library_path,CurrentDirectoryPath,k);
  202.         if(library_path[k-1] != '/'){
  203.                 library_path[k] = '/';
  204.                 k++;
  205.         }
  206.         strcpy(library_path+k,"block.bin");
  207.  
  208.         file = FileOpen(library_path);
  209.         if (!file){
  210.                 MessageBox("Error open file 'block.bin', file not found");
  211.                 return false;
  212.         }
  213.         k = FileGetLength(file);
  214.         if (k > 0){
  215.                 if(b_data) delete b_data;
  216.                 b_data = new unsigned char[k];
  217.  
  218.                 if (b_data){
  219.                         if(FileRead(file, b_data, k) != k){
  220.                                 delete b_data; b_data = 0;
  221.                         }
  222.                         else if((long&)b_data[0]==0x4b43504b){ //"KPCK"
  223.                                 k = (long&)b_data[4];
  224.                                 f_data = new unsigned char[k];
  225.                                 unpack(b_data, f_data);
  226.                                 delete b_data;
  227.                                 b_data = f_data;
  228.                                 f_data = 0;
  229.                         }
  230.                 }
  231.                 FileClose(file);
  232.         }
  233.         else {
  234.                 MessageBox("Error open file 'block.bin', file length == 0");
  235.                 FileClose(file);
  236.                 return false;
  237.         }
  238.  
  239.         if (b_data){
  240.                 unsigned long i=0, n=0;
  241.                 b_count=0;
  242.                 while((long&)b_data[i] && i<k){
  243.                         while(b_data[i]){ i++; };
  244.                         i = (i|3)+1;
  245.                         i += 4+((long&)b_data[i])*24;
  246.                         b_count++;
  247.                 };
  248.                 b_list = new BlockList[b_count];
  249.                 i=0;
  250.                 while((long&)b_data[i] && i<k){
  251.                         b_list[n].name = (unsigned char*)(b_data+i);
  252.                         while(b_data[i]){ i++; };
  253.                         i = (i|3)+1;
  254.                         b_list[n].p_cou = (long&)b_data[i];
  255.                         i += 4;
  256.                         b_list[n].vert_d = (float*)(b_data+i);
  257.                         i += b_list[n].p_cou*12;
  258.                         b_list[n].norm_d = (float*)(b_data+i);
  259.                         i += b_list[n].p_cou*12;
  260.                         compile_list(&b_list[n]);
  261.                         n++;
  262.                 };
  263.         }
  264.         else {
  265.                 MessageBox("Error open file 'block.bin', can't unpack file");
  266.         }
  267.         return (bool)b_data;
  268. }
  269.  
  270. bool init_model()
  271. {
  272.         long i, n, max_time=0;
  273.         char *ft = strstr(f_data, "const");
  274.         char *fe; //end ']'
  275.         char *fp; //perv ','
  276.  
  277.         c_count=0;
  278.         while(ft && c_count<C_COUNT_MAX){
  279.                 fp = ft+5;
  280.                 while(fp[0]==' ') fp++;
  281.                 c_list[c_count].name = fp;
  282.                 ft = strchr(ft, '=')+1;
  283.                 fe = strchr(ft, ';');
  284.                 fe[0] = 0;
  285.                 c_list[c_count].color = StrToInt(ft);
  286.                 fe[0] = ';';
  287.                 c_count++;
  288.                 ft = strstr(ft, "const");
  289.         }
  290.  
  291.         float mz_min=0.0, mz_max=0.0;
  292.         ft = strstr(f_data, "model_list");
  293.         if(ft==0) return false;
  294.  
  295.         m_count=0;
  296.         fe=strchr(ft, ';');
  297.         if(fe==0) return false;
  298.         do{
  299.                 ft=strchr(ft, '[');
  300.                 ft=strchr(ft, ']');
  301.                 if(ft && ft<fe) m_count++;
  302.         }while(ft && ft<fe);
  303.  
  304.         if(model_list) delete model_list;
  305.         model_list = new ModelList[m_count];
  306.  
  307.         ft = strstr(f_data, "model_list");
  308.         ft=strchr(ft, '[')+1;
  309.         for(i=0;i<m_count;i++){
  310.                 ft=strchr(ft, '[')+1;
  311.                 fe=strchr(ft, ']')+1;
  312.                 ft=strchr(ft, '\'')+1;
  313.                 model_list[i].name = ft;
  314.                 ft=strchr(ft, ',')+1; //color
  315.                
  316.                 fp=ft;
  317.                 ft=strchr(ft, ',')+1;
  318.                 ft[-1]=0;
  319.                 n=color_get_id(fp);
  320.                 if(n>-1){
  321.                         model_list[i].color=c_list[n].color;
  322.                 }
  323.                 else{
  324.                         model_list[i].color=StrToInt(fp);
  325.                 }
  326.  
  327.                 fp=ft;
  328.                 ft=strchr(ft, ',')+1;
  329.                 ft[-1]=0;
  330.                 model_list[i].t_cr=StrToInt(fp);
  331.                 if(model_list[i].t_cr>max_time) max_time=model_list[i].t_cr;
  332.  
  333.                 fp=ft;
  334.                 ft=strchr(ft, ',')+1;
  335.                 ft[-1]=0;
  336.                 model_list[i].x=StrToDouble(fp);
  337.  
  338.                 fp=ft;
  339.                 ft=strchr(ft, ',')+1;
  340.                 ft[-1]=0;
  341.                 model_list[i].y=StrToDouble(fp);
  342.  
  343.                 fp=ft;
  344.                 ft=strchr(ft, ',')+1;
  345.                 ft[-1]=0;
  346.                 model_list[i].z=StrToDouble(fp);
  347.  
  348.                 fp=ft;
  349.                 ft=strchr(ft, ',')+1;
  350.                 ft[-1]=0;
  351.                 model_list[i].r_x=StrToDouble(fp);
  352.  
  353.                 fp=ft;
  354.                 ft=strchr(ft, ',')+1;
  355.                 ft[-1]=0;
  356.                 model_list[i].r_y=StrToDouble(fp);
  357.  
  358.                 fp=ft;
  359.                 ft=strchr(ft, ',')+1;
  360.                 if(!ft || fe<ft){
  361.                         ft=fe;
  362.                         model_list[i].level=0;
  363.                         if(mz_min>model_list[i].z) mz_min=model_list[i].z;
  364.                         if(mz_max<model_list[i].z) mz_max=model_list[i].z;
  365.                 }
  366.                 ft[-1]=0;
  367.                 model_list[i].r_z=StrToDouble(fp);
  368.                 if(ft!=fe){
  369.                         fp=ft;
  370.                         ft=fe;
  371.                         ft[-1]=0;
  372.                         model_list[i].level=StrToInt(fp);
  373.                 }
  374.                 model_list[i].id_l = list_get_id(model_list[i].name);
  375.         }
  376.         trans_z = (mz_max-mz_min)/2.0;
  377.         scale_o = .5/trans_z;
  378.         angle_x = 135.0;
  379.         angle_z = -45.0;
  380.         sb_tcr.max_area = max_time+1;
  381.         sb_tcr.position = max_time;
  382.  
  383.         return true;
  384. }
  385.  
  386. void KolibriOnPaint(void);
  387.  
  388. void __stdcall DrawWindow()
  389. {
  390.         asm{
  391.                 push ebx
  392.                 mcall SF_REDRAW,SSF_BEGIN_DRAW
  393.         }
  394.         KolibriOnPaint();
  395.         asm{
  396.                 mcall SF_REDRAW,SSF_END_DRAW
  397.                 pop ebx
  398.         }
  399. }
  400.  
  401. bool OpenModel(char* f_path)
  402. {
  403.         FileInfoBlock* file;
  404.         unsigned long int k;
  405.  
  406.         file = FileOpen(f_path);
  407.         if (!file){
  408.                 SetWindowCaption("Error open file ...");
  409.                 return false;
  410.         }
  411.         k = FileGetLength(file);
  412.         if (k > 0){
  413.                 if(f_data) delete f_data;
  414.                 f_data = new unsigned char[k];
  415.                 if (f_data){
  416.                         if (FileRead(file, f_data, k) != k){
  417.                                 delete f_data; f_data = 0;
  418.                         }
  419.                         else{
  420.                                 init_model();
  421.                                 draw_3d();
  422.                                 SetWindowCaption(ofd.openfile_path);
  423.                                 Redraw(1);
  424.                         }
  425.                 }
  426.         }
  427.         FileClose(file);
  428.         return (bool)f_data;
  429. }
  430.  
  431. bool KolibriOnStart(TStartData &kos_start, TThreadData /*th*/)
  432. {
  433.         kos_start.Left = 10;
  434.         kos_start.Top = 40;
  435.         kos_start.Width = 640;
  436.         kos_start.Height = 480;
  437.         kos_start.WinData.WindowColor = 0x333333;
  438.         kos_start.WinData.WindowType = 0x33; // 0x34 - fixed, 0x33 - not fixed
  439.         kos_start.WinData.Title = header;
  440.  
  441.         if(LoadLibrary("proc_lib.obj", library_path, "/sys/lib/proc_lib.obj", &import_proc_lib))
  442.         {
  443.                 ofd.procinfo = procinfo;
  444.                 ofd.com_area_name = "FFFFFFFF_open_dialog";
  445.                 ofd.com_area = 0;
  446.                 ofd.opendir_path = plugin_path;
  447.                 ofd.dir_default_path = "/rd/1";
  448.                 ofd.start_path = "/rd/1/File managers/opendial";
  449.                 ofd.draw_window = DrawWindow;
  450.                 ofd.status = 0;
  451.                 ofd.openfile_path = openfile_path;
  452.                 ofd.filename_area = filename_area;
  453.                 ofd.filter_area = &filter1;
  454.                 ofd.x_size = 420;
  455.                 ofd.x_start = 10;
  456.                 ofd.y_size = 320;
  457.                 ofd.y_start = 10;
  458.                 OpenDialog_Init(&ofd);
  459.         } else return false;
  460.         if(LoadLibrary("box_lib.obj", library_path, "/sys/lib/box_lib.obj", &import_box_lib))
  461.         {
  462.                 check_box_init(&check1);
  463.                 sb_tcr.ar_offset=1;
  464.         } else return false;
  465.         if(LoadLibrary("tinygl.obj", library_path, "/sys/lib/tinygl.obj", &import_tinygl))
  466.         {
  467.                 long h = kos_start.Height-TOOLBAR_H;
  468.                 kosglMakeCurrent(0,TOOLBAR_H,kos_start.Width,h,&ctx1);
  469.                 rat_h = h;
  470.                 rat_h /= kos_start.Width;
  471.                 angle_dwm = kos_start.Width/180.0;
  472.                 angle_dhm = h/180.0;
  473.                 glEnable(GL_DEPTH_TEST);
  474.                 glClearColor(0.2,0.2,0.2,0.0);
  475.                 glEnable(GL_NORMALIZE);
  476.                 if(init_block()){
  477.                         if(CommandLine[0]) OpenModel(CommandLine);
  478.                         return true;
  479.                 }
  480.         }
  481.         return false;
  482. }
  483.  
  484. void KolibriOnPaint(void)
  485. {
  486.         kosglSwapBuffers();
  487.  
  488.         // If button have ID 1, this is close button
  489.         DrawButton(2,0xf0f0f0, 10,4,50,19);
  490.         DrawText(20,10,0,"Open");
  491.         DrawRect(70,7, 24,18, 0x333333);
  492.         DrawText(70,7,(1<<24)|0xffffff,DoubleToStr(sb_tcr.position,0,true));
  493.         sb_tcr.all_redraw=1;
  494.         scrollbar_h_draw(&sb_tcr);
  495.         check_box_draw(&check1);
  496. }
  497.  
  498. void KolibriOnButton(long id, TThreadData /*th*/)
  499. {
  500.         switch(id){
  501.         case 2:
  502.                 ofd.type = 0; // 0 - open
  503.                 OpenDialog_Start(&ofd);
  504.                 if(ofd.status==1) OpenModel(ofd.openfile_path);
  505.                 //break;
  506.         };
  507. }
  508.  
  509. void KolibriOnKeyPress(TThreadData /*th*/)
  510. {
  511.         long key = GetKey();
  512.         switch(key){
  513.         case 178: //Up
  514.                 angle_x+=delt_size;
  515.                 draw_3d();
  516.                 kosglSwapBuffers();
  517.                 break;
  518.         case 177: //Down
  519.                 angle_x-=delt_size;
  520.                 draw_3d();
  521.                 kosglSwapBuffers();
  522.                 break;
  523.         case 176: //Left
  524.                 angle_z+=delt_size;
  525.                 draw_3d();
  526.                 kosglSwapBuffers();
  527.                 break;
  528.         case 179: //Right
  529.                 angle_z-=delt_size;
  530.                 draw_3d();
  531.                 kosglSwapBuffers();
  532.                 //break;
  533.         };
  534. }
  535.  
  536. void KolibriOnMouse(TThreadData /*th*/)
  537. {
  538.         short m_x_old, m_y_old;
  539.  
  540.         long f, m = sb_tcr.position;
  541.         f = check1.flags;
  542.         scrollbar_h_mouse(&sb_tcr);
  543.         check_box_mouse(&check1);
  544.         if(sb_tcr.position!=m || check1.flags!=f){             
  545.                 draw_3d();
  546.                 Invalidate();
  547.                 return;
  548.         }
  549.  
  550.         m = GetMouseButton();
  551.         if(m&1 && mouse_drag){
  552.                 //mouse l. but. move
  553.                 m_x_old = mouse_x;
  554.                 m_y_old = mouse_y;
  555.                 GetMousePosPicture(mouse_x, mouse_y);
  556.  
  557.                 //если курсор движется по оси y (вверх или вниз) то поворот делаем вокруг оси x
  558.                 angle_x -= (m_y_old - mouse_y) / angle_dwm;
  559.  
  560.                 //если курсор движется по оси x (влево или вправо) то поворот делаем вокруг оси z
  561.                 angle_z -= (m_x_old - mouse_x) / angle_dhm;
  562.  
  563.                 draw_3d();
  564.                 kosglSwapBuffers();
  565.         }
  566.         if(m&0x10000){
  567.                 //mouse l. but. up
  568.                 mouse_drag=false;
  569.         }
  570.         if(m&0x100){
  571.                 //mouse l. but. press
  572.                 GetMousePosPicture(mouse_x, mouse_y);
  573.                 if(mouse_x>0 && mouse_y>TOOLBAR_H) mouse_drag=true;
  574.         }
  575.  
  576.         GetMouseScrollData(m_x_old, m_y_old);
  577.         if(m_y_old<0 && scale_o<0.5){
  578.                 scale_o *= 1.414213562;
  579.                 draw_3d();
  580.                 kosglSwapBuffers();
  581.         }
  582.         else if(m_y_old>0 && scale_o>0.005){
  583.                 scale_o /= 1.414213562;
  584.                 draw_3d();
  585.                 kosglSwapBuffers();
  586.         }
  587. }
  588.  
  589. void KolibriOnSize(int [], TThreadData /*th*/)
  590. {
  591.         unsigned short int width, height;
  592.         GetClientSize(width, height);
  593.         if(!width || !height) return;
  594.         width--;
  595.         height-=TOOLBAR_H;
  596.         if(width<100) width=100;
  597.         if(height<80) height=80;
  598.         rat_h = (float)height / (float)width;
  599.         angle_dwm = (float)width/180.0;
  600.         angle_dhm = (float)height/180.0;
  601.         glViewport(0, 0, width, height);
  602.         draw_3d();
  603. }
  604.  
  605. bool KolibriOnClose(TThreadData /*th*/)
  606. {
  607.         if(b_data){
  608.                 delete b_data;
  609.                 delete b_list;
  610.         }
  611.         if(f_data) delete f_data;
  612.         if(model_list) delete model_list;
  613.         return true;
  614. }