home *** CD-ROM | disk | FTP | other *** search
/ Launch & Play / spustahrej2.iso / Egoboo / code / camera.c next >
Encoding:
C/C++ Source or Header  |  2001-12-03  |  17.5 KB  |  584 lines

  1. // camera.c
  2.  
  3. // Egoboo, Copyright (C) 2000 Aaron Bishop
  4.  
  5. #include "egoboo.h"
  6.  
  7. //--------------------------------------------------------------------------------------------
  8. void camera_look_at(float x, float y)
  9. {
  10.     // ZZ> This function makes the camera turn to face the character
  11.     camzgoto = camzadd;
  12.     if(doturntime != 0)
  13.     {
  14.         camturnleftright = (1.5*PI)-atan2(y-camy, x-camx);  // xgg
  15.     }
  16. }
  17.  
  18. void dump_matrix(GLMATRIX a)
  19. {
  20.   int i; int j;
  21.  
  22.   for(j=0;j<4;j++)
  23.   {
  24.     printf("  ");
  25.     for(i=0;i<4;i++)
  26.       printf("%f ",(a)_CNV(i,j));
  27.     printf("\n");
  28.   }
  29. }
  30.  
  31. //--------------------------------------------------------------------------------------------
  32. void project_view()
  33. {
  34.     // ZZ> This function figures out where the corners of the view area
  35.     //     go when projected onto the plane of the mesh.  Used later for
  36.     //     determining which mesh fans need to be rendered
  37.     
  38.     int cnt, tnc, extra[2];
  39.     float ztemp;
  40.     float numstep;
  41.     float zproject;
  42.     float xfin, yfin, zfin;
  43.     GLMATRIX mTemp;
  44.  
  45.     // Range
  46.     ztemp = (camz);
  47.  
  48.     // Topleft
  49.     //printf("DIAG: In project_view\n");
  50.     //printf("DIAG: dumping mView\n"); dump_matrix(mView);
  51.     //printf("cam xyz,zoom = %f %f %f %f\n",camx,camy,camz,camzoom);
  52.  
  53.     mTemp = MatrixMult(RotateY(-rotmeshtopside*PI/360), mView);
  54.     mTemp = MatrixMult(RotateX(rotmeshup*PI/360), mTemp);
  55.     zproject = (mTemp)_CNV(2,2);                                    //2,2
  56.     // Camera must look down
  57.     if(zproject < 0)
  58.     {
  59.         numstep = -ztemp/zproject;
  60.         xfin = camx+(numstep*(mTemp)_CNV(0,2));  // xgg            //0,2
  61.         yfin = camy+(numstep*(mTemp)_CNV(1,2));                    //1,2
  62.         zfin = 0;
  63.         cornerx[0] = xfin;
  64.         cornery[0] = yfin;
  65.         //printf("Camera TL: %f %f\n",xfin,yfin);
  66.         //dump_matrix(mTemp);
  67.     }
  68.  
  69.     // Topright
  70.     mTemp = MatrixMult(RotateY(rotmeshtopside*PI/360), mView);
  71.     mTemp = MatrixMult(RotateX(rotmeshup*PI/360), mTemp);
  72.     zproject = (mTemp)_CNV(2,2);                                    //2,2
  73.     // Camera must look down
  74.     if(zproject < 0)
  75.     {
  76.         numstep = -ztemp/zproject;
  77.         xfin = camx+(numstep*(mTemp)_CNV(0,2));  // xgg            //0,2
  78.         yfin = camy+(numstep*(mTemp)_CNV(1,2));                    //1,2
  79.         zfin = 0;
  80.         cornerx[1] = xfin;
  81.         cornery[1] = yfin;
  82.         //printf("Camera TR: %f %f\n",xfin,yfin);
  83.         //dump_matrix(mTemp);
  84.     }
  85.  
  86.     // Bottomright
  87.     mTemp = MatrixMult(RotateY(rotmeshbottomside*PI/360), mView);
  88.     mTemp = MatrixMult(RotateX(-rotmeshdown*PI/360), mTemp);
  89.     zproject = (mTemp)_CNV(2,2);                                    //2,2
  90.     // Camera must look down
  91.     if(zproject < 0)
  92.     {
  93.         numstep = -ztemp/zproject;
  94.         xfin = camx+(numstep*(mTemp)_CNV(0,2));  // xgg            //0,2
  95.         yfin = camy+(numstep*(mTemp)_CNV(1,2));                    //1,2
  96.         zfin = 0;
  97.         cornerx[2] = xfin;
  98.         cornery[2] = yfin;
  99.         //printf("Camera BR: %f %f\n",xfin,yfin);
  100.         //dump_matrix(mTemp);
  101.     }
  102.  
  103.     // Bottomleft
  104.     mTemp = MatrixMult(RotateY(-rotmeshbottomside*PI/360), mView);
  105.     mTemp = MatrixMult(RotateX(-rotmeshdown*PI/360), mTemp);
  106.     zproject = (mTemp)_CNV(2,2);                                    //2,2
  107.     // Camera must look down
  108.     if(zproject < 0)
  109.     {
  110.         numstep = -ztemp/zproject;
  111.         xfin = camx+(numstep*(mTemp)_CNV(0,2));  // xgg            //0,2
  112.         yfin = camy+(numstep*(mTemp)_CNV(1,2));                    //1,2
  113.         zfin = 0;
  114.         cornerx[3] = xfin;
  115.         cornery[3] = yfin;
  116.         //printf("Camera BL: %f %f\n",xfin,yfin);
  117.         //dump_matrix(mTemp);
  118.     }
  119.  
  120.     // Get the extreme values
  121.     cornerlowx = cornerx[0];
  122.     cornerlowy = cornery[0];
  123.     cornerhighx = cornerx[0];
  124.     cornerhighy = cornery[0];
  125.     cornerlistlowtohighy[0] = 0;
  126.     cornerlistlowtohighy[3] = 0;
  127.     
  128.     for (cnt = 0; cnt < 4; cnt++)
  129.     {
  130.         if(cornerx[cnt] < cornerlowx)
  131.             cornerlowx=cornerx[cnt];
  132.         if(cornery[cnt] < cornerlowy)
  133.         {
  134.             cornerlowy=cornery[cnt];
  135.             cornerlistlowtohighy[0] = cnt;
  136.         }
  137.         if(cornerx[cnt] > cornerhighx)
  138.             cornerhighx=cornerx[cnt];
  139.         if(cornery[cnt] > cornerhighy)
  140.         {
  141.             cornerhighy=cornery[cnt];
  142.             cornerlistlowtohighy[3] = cnt;
  143.         }
  144.     }
  145.  
  146.     // Figure out the order of points
  147.     tnc = 0;
  148.     for (cnt = 0; cnt < 4; cnt++)
  149.     {
  150.         if(cnt != cornerlistlowtohighy[0] && cnt != cornerlistlowtohighy[3])
  151.         {
  152.             extra[tnc] = cnt;
  153.             tnc++;
  154.         }
  155.     }
  156.     cornerlistlowtohighy[1] = extra[1];
  157.     cornerlistlowtohighy[2] = extra[0];
  158.     if(cornery[extra[0]] < cornery[extra[1]])
  159.     {
  160.         cornerlistlowtohighy[1] = extra[0];
  161.         cornerlistlowtohighy[2] = extra[1];
  162.     }
  163.  
  164.     // BAD: exit here
  165.     //printf("Corners:\n");
  166.     //printf("x: %d %d\n",cornerlowx,cornerhighx);
  167.     //printf("y: %d %d\n",cornerlowy,cornerhighy);
  168.     /*printf("Exiting, camera code is broken\n");
  169.     exit(0);*/
  170. }
  171.  
  172. //--------------------------------------------------------------------------------------------
  173. void make_camera_matrix()
  174. {
  175.     // ZZ> This function sets mView to the camera's location and rotation
  176.     mView = mViewSave;
  177.     mView = MatrixMult(Translate(camx, -camy, camz), mView);  // xgg
  178.     if(camswingamp > .001)
  179.     {
  180.         camroll = turntosin[camswing]*camswingamp;
  181.         mView = MatrixMult(RotateY(camroll), mView);
  182.     }
  183.     mView = MatrixMult(RotateZ(camturnleftright), mView);
  184.     mView = MatrixMult(RotateX(camturnupdown), mView);
  185.     //lpD3DDDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &mView);
  186. //        glMatrixMode(GL_MODELVIEW);
  187. ///        glLoadMatrixf(mView.v);
  188. }
  189.  
  190. //--------------------------------------------------------------------------------------------
  191. void bound_camera()
  192. {
  193.     // ZZ> This function stops the camera from moving off the mesh
  194.     if(camx < EDGE)  camx = EDGE;
  195.     if(camx > meshedgex-EDGE)  camx = meshedgex-EDGE;
  196.     if(camy < EDGE)  camy = EDGE;
  197.     if(camy > meshedgey-EDGE)  camy = meshedgey-EDGE;
  198. }
  199.  
  200. //--------------------------------------------------------------------------------------------
  201. void bound_camtrack()
  202. {
  203.     // ZZ> This function stops the camera target from moving off the mesh
  204.     if(usefaredge)
  205.     {
  206.         if(camtrackx < FARTRACK)  camtrackx = FARTRACK;
  207.         if(camtrackx > meshedgex-FARTRACK)  camtrackx = meshedgex-FARTRACK;
  208.         if(camtracky < FARTRACK)  camtracky = FARTRACK;
  209.         if(camtracky > meshedgey-FARTRACK)  camtracky = meshedgey-FARTRACK;
  210.     }
  211.     else
  212.     {
  213.         if(camtrackx < EDGETRACK)  camtrackx = EDGETRACK;
  214.         if(camtrackx > meshedgex-EDGETRACK)  camtrackx = meshedgex-EDGETRACK;
  215.         if(camtracky < EDGETRACK)  camtracky = EDGETRACK;
  216.         if(camtracky > meshedgey-EDGETRACK)  camtracky = meshedgey-EDGETRACK;
  217.     }
  218. }
  219.  
  220. //--------------------------------------------------------------------------------------------
  221. void adjust_camera_angle(int height)
  222. {
  223.   // ZZ> This function makes the camera look downwards as it is raised up
  224.   float percentmin, percentmax;
  225.  
  226.  
  227.   if(height < MINZADD)  height = MINZADD;
  228.   percentmax = (height-MINZADD)/(float)(MAXZADD-MINZADD);
  229.   percentmin = 1.0-percentmax;
  230.  
  231.   camturnupdown = ((MINUPDOWN*percentmin)+(MAXUPDOWN*percentmax));
  232.   camzoom = (MINZOOM*percentmin)+(MAXZOOM*percentmax);
  233. }
  234.  
  235. //--------------------------------------------------------------------------------------------
  236. void move_camera()
  237. {
  238.     // ZZ> This function moves the camera
  239.     int cnt, locoalive, band, movex, movey;
  240.     float x, y, z, level, newx, newy;
  241.     unsigned short character, turnsin, turncos;
  242.  
  243.     //printf("DIAG: In move_camera\n");
  244.     //dump_matrix(mView);
  245.  
  246.     if(autoturncamera)
  247.         doturntime = 255;
  248.     else if(doturntime != 0)  
  249.         doturntime--;
  250.     
  251.     x = 0;
  252.     y = 0;
  253.     z = 0;
  254.     level = 0;
  255.     locoalive = 0;
  256.     
  257.     for (cnt = 0; cnt < MAXPLAYER; cnt++)
  258.     {
  259.         if(plavalid[cnt] && pladevice[cnt] != INPUTNONE)
  260.         {
  261.             character = plaindex[cnt];
  262.             if(chralive[character])
  263.             {
  264.                 if(chrattachedto[character]==MAXCHR)
  265.                 {
  266.                     // The character is on foot
  267.                     x+=chrxpos[character];
  268.                     y+=chrypos[character];
  269.                     z+=chrzpos[character];
  270.                     level+=chrlevel[character];
  271.                 }
  272.                 else
  273.                 {
  274.                     // The character is mounted
  275.                     x+=chrxpos[chrattachedto[character]];
  276.                     y+=chrypos[chrattachedto[character]];
  277.                     z+=chrzpos[chrattachedto[character]];
  278.                     level+=chrlevel[chrattachedto[character]];
  279.                 }
  280.                 locoalive++;
  281.             }
  282.         }
  283.     }
  284.  
  285.     if(locoalive>0)
  286.     {
  287.         x=x/locoalive;
  288.         y=y/locoalive;
  289.         z=z/locoalive;
  290.         level=level/locoalive;
  291.     }
  292.     else
  293.     {
  294.         x = camtrackx;
  295.         y = camtracky;
  296.         z = camtrackz;
  297.     }
  298.  
  299.     if(rtscontrol)
  300.     {
  301.         if(mousebutton[0])
  302.         {
  303.             x = camtrackx;
  304.             y = camtracky;
  305.         }
  306.         else
  307.         {
  308.             band = 50;
  309.             movex = 0;
  310.             movey = 0;
  311.             if(cursorx < band+6)
  312.                 movex += -(band+6-cursorx);
  313.             if(cursorx > scrx-band-16)
  314.                 movex += cursorx+16-scrx+band;
  315.             if(cursory < band+8)
  316.                 movey += -(band+8-cursory);
  317.             if(cursory > scry-band-24)
  318.                 movey += cursory+24-scry+band;
  319.             turnsin = (camturnleftrightone*16383);
  320.             turnsin = turnsin&16383;
  321.             turncos = (turnsin+4096)&16383;
  322.             x = (movex*turntosin[turncos]+movey*turntosin[turnsin])*rtsscrollrate;
  323.             y = (-movex*turntosin[turnsin]+movey*turntosin[turncos])*rtsscrollrate;
  324.             camx = (camx + camx + x)/2.0;
  325.             camy = (camy + camy + y)/2.0;
  326.             x = camtrackx+x;
  327.             y = camtracky+y;
  328.         }
  329.         if(rtssetcamera)
  330.         {
  331.             x = rtssetcamerax;
  332.             y = rtssetcameray;
  333.         }
  334.         z = camtrackz;
  335.     }
  336.     camtrackxvel = -camtrackx;
  337.     camtrackyvel = -camtracky;
  338.     camtrackzvel = -camtrackz;
  339.     camtrackx = (camtrackx+x)/2.0;
  340.     camtracky = (camtracky+y)/2.0;
  341.     camtrackz = (camtrackz+z)/2.0;
  342.     camtracklevel = (camtracklevel+level)/2.0;
  343.  
  344.  
  345.     camturnadd=camturnadd*camsustain;
  346.     camzadd = (camzadd*3.0 + camzaddgoto)/4.0;
  347.     camz = (camz*3.0 + camzgoto)/4.0;
  348.     // Camera controls
  349.     if(autoturncamera == 255 && numlocalpla==1)
  350.     {
  351.         if(mouseon)
  352.           if(!control_mouse_is_pressed(MOS_CAMERA))
  353.             camturnadd-=(mousex*.5);
  354.         if(keyon)
  355.           camturnadd+=(control_key_is_pressed(KEY_LEFT)-control_key_is_pressed(KEY_RIGHT))*(CAMKEYTURN);
  356.         if(joyaon)
  357.           if(!control_joya_is_pressed(JOA_CAMERA))
  358.             camturnadd-=joyax*CAMJOYTURN;
  359.         if(joybon)
  360.           if(!control_joyb_is_pressed(JOB_CAMERA))
  361.             camturnadd-=joybx*CAMJOYTURN;
  362.     }
  363.     else
  364.     {
  365.         if(mouseon)
  366.         {
  367.             if(control_mouse_is_pressed(MOS_CAMERA))
  368.             {
  369.                 camturnadd+=(mousex/3.0);
  370.                 camzaddgoto+=(float) mousey/3.0;
  371.                 if(camzaddgoto < MINZADD)  camzaddgoto = MINZADD;
  372.                 if(camzaddgoto > MAXZADD)  camzaddgoto = MAXZADD;
  373.                 doturntime = TURNTIME;  // Sticky turn...
  374.             }
  375.         }
  376.         // JoyA camera controls
  377.         if(joyaon)
  378.         {
  379.             if(control_joya_is_pressed(JOA_CAMERA))
  380.             {
  381.                 camturnadd+=joyax*CAMJOYTURN;
  382.                 camzaddgoto+=joyay*CAMJOYTURN;
  383.                 if(camzaddgoto < MINZADD)  camzaddgoto = MINZADD;
  384.                 if(camzaddgoto > MAXZADD)  camzaddgoto = MAXZADD;
  385.                 doturntime = TURNTIME;  // Sticky turn...
  386.             }
  387.         }
  388.         // JoyB camera controls
  389.         if(joybon)
  390.         {
  391.             if(control_joyb_is_pressed(JOB_CAMERA))
  392.             {
  393.                 camturnadd+=joybx*CAMJOYTURN;
  394.                 camzaddgoto+=joyby*CAMJOYTURN;
  395.                 if(camzaddgoto < MINZADD)  camzaddgoto = MINZADD;
  396.                 if(camzaddgoto > MAXZADD)  camzaddgoto = MAXZADD;
  397.                 doturntime = TURNTIME;  // Sticky turn...
  398.             }
  399.         }
  400.     }
  401.     // Keyboard camera controls
  402.     if(keyon)
  403.     {
  404.         if(control_key_is_pressed(KEY_CAMERA_LEFT)||control_key_is_pressed(KEY_CAMERA_RIGHT))
  405.         {
  406.             camturnadd+=(control_key_is_pressed(KEY_CAMERA_LEFT)-control_key_is_pressed(KEY_CAMERA_RIGHT))*CAMKEYTURN;
  407.             doturntime = TURNTIME;  // Sticky turn...
  408.         }
  409.         if(control_key_is_pressed(KEY_CAMERA_IN)||control_key_is_pressed(KEY_CAMERA_OUT))
  410.         {
  411.             camzaddgoto+=(control_key_is_pressed(KEY_CAMERA_OUT)-control_key_is_pressed(KEY_CAMERA_IN))*CAMKEYTURN;
  412.             if(camzaddgoto < MINZADD)  camzaddgoto = MINZADD;
  413.             if(camzaddgoto > MAXZADD)  camzaddgoto = MAXZADD;
  414.         }
  415.     }
  416.     camx-=(float) ((mView)_CNV(0,0))*camturnadd;  // xgg
  417.     camy+=(float) ((mView)_CNV(1,0))*-camturnadd;
  418.  
  419.     // Make it not break...
  420.     bound_camtrack();
  421.     bound_camera();
  422.  
  423.     // Do distance effects for overlay and background
  424.     camtrackxvel += camtrackx;
  425.     camtrackyvel += camtracky;
  426.     camtrackzvel += camtrackz;
  427.     if(overlayon)
  428.     {
  429.         // Do fg distance effect
  430.         waterlayeru[0] += camtrackxvel*waterlayerdistx[0];
  431.         waterlayerv[0] += camtrackyvel*waterlayerdisty[0];
  432.     }
  433.     if(clearson==FALSE)
  434.     {
  435.         // Do bg distance effect
  436.         waterlayeru[1] += camtrackxvel*waterlayerdistx[1];
  437.         waterlayerv[1] += camtrackyvel*waterlayerdisty[1];
  438.     }
  439.  
  440.     // Center on target for doing rotation...
  441.     if(doturntime != 0)
  442.     {
  443.         camcenterx = camcenterx*.9 + camtrackx*.1;
  444.         camcentery = camcentery*.9 + camtracky*.1;
  445.     }
  446.  
  447.     // Create a tolerance area for walking without camera movement
  448.     x = camtrackx - camx;
  449.     y = camtracky - camy;
  450.     newx = -((mView)_CNV(0,0) * x + (mView)_CNV(1,0) * y); //newx = -(mView(0,0) * x + mView(1,0) * y);
  451.     newy = -((mView)_CNV(0,1) * x + (mView)_CNV(1,1) * y);   //newy = -(mView(0,1) * x + mView(1,1) * y);
  452.  
  453.  
  454.     // Debug information
  455.     //sprintf(generictext, "%f %f", newx, newy);
  456.     //debug_message(generictext);
  457.  
  458.     // Get ready to scroll...
  459.     movex = 0;
  460.     movey = 0;
  461.  
  462.     // Adjust for camera height...
  463.     z = (TRACKXAREALOW  * (MAXZADD - camzadd)) +
  464.         (TRACKXAREAHIGH * (camzadd - MINZADD));
  465.     z = z / (MAXZADD - MINZADD);
  466.     if(newx < -z)
  467.     {
  468.         // Scroll left
  469.         movex += (newx + z);
  470.     }
  471.     if(newx > z)
  472.     {
  473.         // Scroll right
  474.         movex += (newx - z);
  475.     }
  476.     
  477.     // Adjust for camera height...
  478.     z = (TRACKYAREAMINLOW  * (MAXZADD - camzadd)) +
  479.         (TRACKYAREAMINHIGH * (camzadd - MINZADD));
  480.     z = z / (MAXZADD - MINZADD);
  481.  
  482.     if(newy < z)
  483.     {
  484.         // Scroll down
  485.         movey -= (newy - z);
  486.     }
  487.     else
  488.     {
  489.         // Adjust for camera height...
  490.         z = (TRACKYAREAMAXLOW  * (MAXZADD - camzadd)) +
  491.             (TRACKYAREAMAXHIGH * (camzadd - MINZADD));
  492.         z = z / (MAXZADD - MINZADD);
  493.         if(newy > z)
  494.         {
  495.             // Scroll up
  496.             movey -= (newy - z);
  497.         }
  498.     }
  499.  
  500.     turnsin = (camturnleftrightone*16383);
  501.     turnsin = turnsin&16383;
  502.     turncos = (turnsin+4096)&16383;
  503.     camcenterx += (movex*turntosin[turncos]+movey*turntosin[turnsin]);
  504.     camcentery += (-movex*turntosin[turnsin]+movey*turntosin[turncos]);
  505.  
  506.     // Finish up the camera
  507.     camera_look_at(camcenterx,camcentery);
  508.     camx=(float) camcenterx+(camzoom*sin(camturnleftright));
  509.     camy=(float) camcentery+(camzoom*cos(camturnleftright));
  510.     bound_camera();
  511. //        adjust_camera_angle(camz-camtracklevel);
  512.     adjust_camera_angle(camz);
  513.  
  514.     make_camera_matrix();
  515. }
  516.  
  517. //--------------------------------------------------------------------------------------------
  518. void reset_camera()
  519. {
  520.     // ZZ> This function makes sure the camera starts in a suitable position
  521.     int cnt, save;
  522. //    int mi;
  523.  
  524.  
  525.     camswing = 0;
  526.     camx = meshedgex/2;
  527.     camy = meshedgey/2;
  528.     camz = 800;
  529.     camzoom = 1000;
  530.     rtsx = 0;
  531.     rtsy = 0;
  532.     camtrackxvel = 0;
  533.     camtrackyvel = 0;
  534.     camtrackzvel = 0;
  535.     camcenterx = camx;
  536.     camcentery = camy;
  537.     camtrackx = camx;
  538.     camtracky = camy;
  539.     camtrackz = 0;
  540.     camturnadd = 0;
  541.     camtracklevel = 0;
  542.     camzadd = 800;
  543.     camzaddgoto = 800;
  544.     camzgoto = 800;
  545.     camturnleftright = (float) (-PI/4);
  546.     camturnleftrightone = (float) (-PI/4)/(2*PI);
  547.     camturnleftrightshort = 0;
  548.     camturnupdown = (float) (PI/4);
  549.     camroll = 0;
  550.     rtssetcamera = TRUE;
  551.     if(rtscontrol)
  552.     {
  553.         rtssetcamerax = meshedgex/2;
  554.         rtssetcameray = meshedgey/2;
  555.         
  556.         for (cnt = 0; cnt < MAXCHR; cnt++)
  557.             if(chron[cnt] && chrteam[cnt] == rtslocalteam)
  558.             {
  559.                 rtssetcamerax = chrxpos[cnt];
  560.                 rtssetcameray = chrypos[cnt];
  561.             }
  562.     }
  563.  
  564.     // Now move the camera towards the players
  565.     mView = ZeroMatrix();
  566.     
  567.     save = autoturncamera;
  568.     autoturncamera = TRUE;
  569.     
  570.     for (cnt = 0; cnt < 32; cnt++)
  571.     {
  572.         move_camera();
  573.         camcenterx = camtrackx;
  574.         camcentery = camtracky;
  575.     }
  576.  
  577.     autoturncamera = save;
  578.     doturntime = 0;
  579.     rtssetcamera = FALSE;
  580.     rtsx = camtrackx;
  581.     rtsy = camtracky;
  582. }
  583.  
  584.