1 #include <GL/glut.h>
2 #include <GL/glu.h>
3 #include <GL/gl.h>
4 #include <math.h>
5 #include <unistd.h>
6 
7 #include "init.h"
8 #include "globals.h"
9 #include "sizes.h"
10 #include "input.h"
11 #include "game.h"
12 #include "status.h"
13 #include "menu.h"
14 #include "netdata.h"
15 #include "network.h"
16 #include "star.h"
17 #include "texture.h"
18 #include "object.h"
19 #include "ship.h"
20 
21 
22 struct TransparencyQueue {
23   int ObjectNumber;
24   float zPosition;
25   int Type;
26 };
27 
28 
29 struct Color White, Black, DarkRed, Red, Green, Blue, LightGray, Gray, DarkGray;
30 GLuint texture[6];
31 struct TransparencyQueue TransparenciesQueue[MAX_OBJECTS+MAX_PLAYERS];
32 int ReverseView;
33 
34 
35 void DrawTriangle(struct Point *point1, struct Point *point2,
36                   struct Point *point3, struct Color *Point1Color,
37                   struct Color *Point2Color, struct Color *Point3Color);
38 void CalcPoint(struct Point *point, struct Point *newpoint);
39 void CalcPointWithRotation(struct Point *point);
40 void CalcPointWithRotation(struct Point *point, struct Point *newpoint,
41                            struct Point *Position, float RotationMatrix[3][3],
42                            float Size);
43 void CalcPosition(struct Point *Position, struct Point *newPosition);
44 void DrawPoint(float xpos, float ypos, struct Color *PointColor);
45 void DrawPoint(struct Point *Position, struct Color *PointColor);
46 void DrawPoint(struct Point *Position, struct Color *PointColor, float Offset, int type);
47 void DrawCircle(int xpos, int ypos, struct Color *CircleColor,
48                 int numPoints, float Size, int offset);
49 void DrawCircle(Object *Obj, struct Color *CircleColor, float InternalTransparency,
50                 float ExternalTransparency, int numPoints, float Size);
51 void DrawExplosion(struct Point *Position, float Age, int Type);
52 void QueueTransparency(struct Point *Position, int objectnum, int Type);
53 void DrawObject(Object *Obj);
54 void DrawCrosshairs();
55 void InitMatrixMode();
56 void SetupGameMatrixMode();
57 
58 
DrawTest()59 void DrawTest()
60 {
61   /*  glBegin(GL_TRIANGLES);
62   glColor4f(1.0, 1.0, 1.0, 1.0);
63   glVertex3f(-0.025, -0.03, -1.0);
64   glVertex3f(0.0, 0.03, -1.0);
65   glVertex3f(-0.018, -0.03, -1.0);
66 
67   glVertex3f(-0.018, -0.03, -1.0);
68   glVertex3f(0.0, 0.03, -1.0);
69   glVertex3f(0.0, 0.015, -1.0);
70 
71   glVertex3f(0.025, -0.03, -1.0);
72   glVertex3f(0.0, 0.03, -1.0);
73   glVertex3f(0.018, -0.03, -1.0);
74 
75   glVertex3f(0.018, -0.03, -1.0);
76   glVertex3f(0.0, 0.03, -1.0);
77   glVertex3f(0.0, 0.015, -1.0);
78 
79   glVertex3f(-0.009, -0.007, -1.0);
80   glVertex3f(-0.009, 0.0, -1.0);
81   glVertex3f(0.009, -0.007, -1.0);
82 
83   glVertex3f(0.009, 0.0, -1.0);
84   glVertex3f(-0.009, 0.0, -1.0);
85   glVertex3f(0.009, -0.007, -1.0);
86   glEnd();*/
87 }
88 
89 
DrawCrosshairs()90 void DrawCrosshairs()
91 {
92   struct Color CrossColor;
93 
94   CrossColor.red=0.0;
95   CrossColor.green=0.0;
96   CrossColor.blue=0.55;
97 
98   glColor4f(CrossColor.red, CrossColor.green, CrossColor.blue, 0.5);
99   glBegin(GL_TRIANGLES);
100   glVertex3f(0.0, 0.005, -0.1);
101   glVertex3f(0.002, 0.01, -0.1);
102   glVertex3f(-0.002, 0.01, -0.1);
103   glVertex3f(0.0, -0.005, -0.1);
104   glVertex3f(0.002, -0.01, -0.1);
105   glVertex3f(-0.002, -0.01, -0.1);
106   glVertex3f(0.005, 0.0, -0.1);
107   glVertex3f(0.01, 0.002, -0.1);
108   glVertex3f(0.01, -0.002, -0.1);
109   glVertex3f(-0.005, 0.0, -0.1);
110   glVertex3f(-0.01, 0.002, -0.1);
111   glVertex3f(-0.01, -0.002, -0.1);
112   glEnd();
113 }
114 
DrawCircle(int xpos,int ypos,struct Color * CircleColor,int numPoints,float Size,int offset)115 void DrawCircle(int xpos, int ypos, struct Color *CircleColor,
116                 int numPoints, float Size, int offset)
117 {
118   float xCenter, yCenter;
119   float xpoint1, xpoint2, ypoint1, ypoint2;
120   int i;
121   float twoPI=2.0*3.14159265358;
122 
123   xCenter=xpos;
124   yCenter=ypos;
125 
126   xCenter=(xCenter/ScreenWidth)*2.0-1.0;
127   yCenter=(yCenter/ScreenHeight)*2.0-1.0;
128 
129   if (offset!=0) {
130     glBegin(GL_LINES);
131     glColor3f(CircleColor->red, CircleColor->green, CircleColor->blue);
132     for (i=offset; i<numPoints; i+=8) {
133       glVertex2f(xCenter+cos((twoPI/(float)numPoints)*(float)i)*Size,
134                  yCenter+sin((twoPI/(float)numPoints)*(float)i)*Size);
135       glVertex2f(xCenter+cos((twoPI/(float)numPoints)*(float)(i+2))*Size,
136                  yCenter+sin((twoPI/(float)numPoints)*(float)(i+2))*Size);
137     }
138   } else {
139     glBegin(GL_LINE_LOOP);
140     for (i=0; i<numPoints; i++) {
141       glVertex2f(xCenter+cos((twoPI/(float)numPoints)*(float)i)*Size,
142                  yCenter+sin((twoPI/(float)numPoints)*(float)i)*Size);
143     }
144   }
145   glEnd();
146 }
147 
148 
DrawCircle(Object * Obj,struct Color * CircleColor,float InternalTransparency,float ExternalTransparency,int numPoints,float Size)149 void DrawCircle(Object *Obj, struct Color *CircleColor, float InternalTransparency,
150                 float ExternalTransparency, int numPoints, float Size)
151 {
152   float twoPI=2.0*3.14159265358;
153   struct Point tempPoint;
154   struct Point newPosition;
155   float Distance;
156   int i;
157 
158   tempPoint.x=0.0;
159   tempPoint.y=0.0;
160   tempPoint.z=0.0;
161 
162   CalcPosition(&Obj->Position, &newPosition);
163   CalcPointWithRotation(&newPosition);
164   Distance=sqrt(newPosition.x*newPosition.x+newPosition.y*newPosition.y+
165                 newPosition.z*newPosition.z);
166 
167   if (ReverseView) {
168     newPosition.z*=-1.0;
169   }
170 
171   if (Distance > Size) {
172     newPosition.x-=Size*(newPosition.x/Distance);
173     newPosition.y-=Size*(newPosition.y/Distance);
174     newPosition.z-=Size*(newPosition.z/Distance);
175   }
176 
177   glBegin(GL_TRIANGLES);
178   for (i=0; i<numPoints; i++) {
179     glColor4f(CircleColor->red, CircleColor->green, CircleColor->blue, InternalTransparency);
180     glVertex3f(newPosition.x, newPosition.y, newPosition.z);
181     glColor4f(CircleColor->red, CircleColor->green, CircleColor->blue, ExternalTransparency);
182     glVertex3f(newPosition.x+cos((twoPI/(float)numPoints)*(float)i)*Size,
183                newPosition.y+sin((twoPI/(float)numPoints)*(float)i)*Size,
184                newPosition.z);
185     glVertex3f(newPosition.x+cos((twoPI/(float)numPoints)*(float)(i+1))*Size,
186                newPosition.y+sin((twoPI/(float)numPoints)*(float)(i+1))*Size,
187                newPosition.z);
188   }
189   glEnd();
190 }
191 
192 
InitTransparencyQueue()193 void InitTransparencyQueue()
194 {
195   int i;
196 
197   for (i=0; i<MAX_OBJECTS+MAX_PLAYERS; i++) {
198     TransparenciesQueue[i].ObjectNumber=-1;
199   }
200 }
201 
202 
QueueTransparency(struct Point * Position,int objectnum,int Type)203 void QueueTransparency(struct Point *Position, int objectnum, int Type)
204 {
205   int i, j;
206   struct Point relPosition;
207 
208   CalcPoint(Position, &relPosition);
209   if (ReverseView) {
210     relPosition.z*=-1.0;
211   }
212 
213   if (relPosition.z < 0.0) {
214     for (i=0; i<MAX_OBJECTS+MAX_PLAYERS; i++) {
215       if (TransparenciesQueue[i].ObjectNumber==-1) {
216         TransparenciesQueue[i].ObjectNumber=objectnum;
217         TransparenciesQueue[i].zPosition=relPosition.z;
218         TransparenciesQueue[i].Type=Type;
219         break;
220       } else if (relPosition.z < TransparenciesQueue[i].zPosition) {
221         for (j=MAX_OBJECTS-1; j>i; j--) {
222           TransparenciesQueue[j].ObjectNumber=TransparenciesQueue[j-1].ObjectNumber;
223           TransparenciesQueue[j].zPosition=TransparenciesQueue[j-1].zPosition;
224           TransparenciesQueue[j].Type=TransparenciesQueue[j-1].Type;
225         }
226         TransparenciesQueue[i].ObjectNumber=objectnum;
227         TransparenciesQueue[i].zPosition=relPosition.z;
228         TransparenciesQueue[i].Type=Type;
229         break;
230       }
231     }
232   }
233 }
234 
235 
DrawExplosion(struct Point * Position,float Age,int Type)236 void DrawExplosion(struct Point *Position, float Age, int Type)
237 {
238   struct Point relPosition;
239   float Size;
240 
241   glEnable(GL_TEXTURE_2D);
242 
243   if (Type==EXPLOSION_TYPE) {
244     Size=0.05*(1.0+2.0*Age);
245   } else {
246     Size=0.2*(0.25+2.0*Age);
247   }
248 
249   if (Age < 1.0) {
250       CalcPoint(Position, &relPosition);
251       if (ReverseView) {
252         relPosition.z*=-1.0;
253       }
254 
255       glBindTexture(GL_TEXTURE_2D, texture[0]);
256 
257       glColor4f(1.0, 1.0, 1.0, 1.0-Age);
258 
259       glBegin(GL_QUADS);
260       glTexCoord2f(0, 1); glVertex3f(-Size+relPosition.x, Size+relPosition.y, relPosition.z);
261       glTexCoord2f(0, 0); glVertex3f(-Size+relPosition.x, -Size+relPosition.y, relPosition.z);
262       glTexCoord2f(1, 0); glVertex3f(Size+relPosition.x, -Size+relPosition.y, relPosition.z);
263       glTexCoord2f(1, 1); glVertex3f(Size+relPosition.x, Size+relPosition.y, relPosition.z);
264       glEnd();
265   }
266 
267   glDisable(GL_TEXTURE_2D);
268 }
269 
270 
DrawTransparencies()271 void DrawTransparencies()
272 {
273   int i;
274   struct Color ShieldColor;
275   struct Color PowerupColor;
276   struct Color NukeExplosionColor;
277 
278   ShieldColor.red=0.5;
279   ShieldColor.green=0.4;
280   ShieldColor.blue=1.0;
281 
282   PowerupColor.red=0.4;
283   PowerupColor.green=0.6;
284   PowerupColor.blue=0.0;
285 
286   NukeExplosionColor.red=0.6;
287   NukeExplosionColor.green=0.0;
288   NukeExplosionColor.blue=0.0;
289 
290   for (i=0; i<MAX_OBJECTS+MAX_PLAYERS; i++) {
291     if (TransparenciesQueue[i].ObjectNumber!=-1) {
292       if (TransparenciesQueue[i].Type==1) {
293         DrawExplosion(&Objects[TransparenciesQueue[i].ObjectNumber]->Position, Objects[TransparenciesQueue[i].ObjectNumber]->Age, Objects[TransparenciesQueue[i].ObjectNumber]->Type);
294       } else if (TransparenciesQueue[i].Type==2) {
295         DrawCircle(Ships[TransparenciesQueue[i].ObjectNumber], &ShieldColor,
296                    0.15, 0.5, 64, Ships[TransparenciesQueue[i].ObjectNumber]->Size);
297       } else if (TransparenciesQueue[i].Type==3) {
298         DrawCircle(Objects[TransparenciesQueue[i].ObjectNumber], &PowerupColor,
299                    0.3, 0.5, 64, Objects[TransparenciesQueue[i].ObjectNumber]->Size);
300       } else if (TransparenciesQueue[i].Type==4) {
301         DrawCircle(Objects[TransparenciesQueue[i].ObjectNumber], &NukeExplosionColor,
302                    0.5, 0.35, 256, Objects[TransparenciesQueue[i].ObjectNumber]->Size);
303       }
304     }
305   }
306 }
307 
308 
309 // Function to draw a line on the screen
DrawLine(int x1pos,int y1pos,int x2pos,int y2pos,struct Color * LineColor)310 void DrawLine(int x1pos, int y1pos, int x2pos, int y2pos, struct Color *LineColor)
311 {
312   float x1, y1, x2, y2;
313 
314   x1=x1pos;
315   y1=y1pos;
316   x2=x2pos;
317   y2=y2pos;
318 
319   x1=(x1/ScreenWidth)*2.0-1.0;
320   y1=(y1/ScreenHeight)*2.0-1.0;
321   x2=(x2/ScreenWidth)*2.0-1.0;
322   y2=(y2/ScreenHeight)*2.0-1.0;
323 
324   glBegin(GL_LINES);
325   glColor3f(LineColor->red, LineColor->green, LineColor->blue);
326   glVertex2f(x1, y1);
327   glVertex2f(x2, y2);
328   glEnd();
329 }
330 
331 
332 /*
333   Function to draw a point on the screen
334   glDrawPixels is used instead of glVertex2f, because the points were showing
335   up in front of the blits
336 */
DrawPoint(int xpos,int ypos,struct Color * PointColor)337 void DrawPoint(int xpos, int ypos, struct Color *PointColor)
338 {
339   float x, y;
340 
341   x=xpos;
342   y=ypos;
343 
344   x=(x/ScreenWidth)*2.0-1.0;
345   y=(y/ScreenHeight)*2.0-1.0;
346 
347   glBegin(GL_POINTS);
348   glColor3f(PointColor->red, PointColor->green, PointColor->blue);
349   glVertex2f(x, y);
350   glEnd();
351 }
352 
353 
DrawPoint(struct Point * Position,struct Color * PointColor)354 void DrawPoint(struct Point *Position, struct Color *PointColor)
355 {
356   struct Point tempPosition;
357 
358   tempPosition.x=Ships[myShip]->CameraMatrix[0][0]*Position->x+Ships[myShip]->CameraMatrix[0][1]*Position->y+Ships[myShip]->CameraMatrix[0][2]*Position->z;
359   tempPosition.y=Ships[myShip]->CameraMatrix[1][0]*Position->x+Ships[myShip]->CameraMatrix[1][1]*Position->y+Ships[myShip]->CameraMatrix[1][2]*Position->z;
360   tempPosition.z=Ships[myShip]->CameraMatrix[2][0]*Position->x+Ships[myShip]->CameraMatrix[2][1]*Position->y+Ships[myShip]->CameraMatrix[2][2]*Position->z;
361 
362   if (ReverseView) {
363     tempPosition.z*=-1.0;
364   }
365 
366   if (tempPosition.z > 0.0) {
367     return;
368   }
369 
370   // Check if point is within radar
371   if (tempPosition.x < 3.0 && tempPosition.x > -3.0 &&
372       tempPosition.y < -3.0 && tempPosition.y > -7.0) {
373     return;
374   }
375 
376   glBegin(GL_POINTS);
377   glColor3f(PointColor->red, PointColor->green, PointColor->blue);
378   glVertex3f(tempPosition.x, tempPosition.y, tempPosition.z);
379   glEnd();
380 }
381 
382 
DrawPoint(struct Point * Position,struct Color * PointColor,float Offset,int type)383 void DrawPoint(struct Point *Position, struct Color *PointColor, float Offset, int type)
384 {
385   struct Point tempPosition;
386 
387   tempPosition.x=Ships[myShip]->CameraMatrix[0][0]*Position->x+Ships[myShip]->CameraMatrix[0][1]*Position->y+Ships[myShip]->CameraMatrix[0][2]*Position->z;
388   tempPosition.y=Ships[myShip]->CameraMatrix[1][0]*Position->x+Ships[myShip]->CameraMatrix[1][1]*Position->y+Ships[myShip]->CameraMatrix[1][2]*Position->z;
389   tempPosition.z=Ships[myShip]->CameraMatrix[2][0]*Position->x+Ships[myShip]->CameraMatrix[2][1]*Position->y+Ships[myShip]->CameraMatrix[2][2]*Position->z;
390 
391   if (type==0) {
392     tempPosition.x+=Offset;
393   } else if (type==1) {
394     tempPosition.y+=Offset;
395   } else {
396     tempPosition.z+=Offset;
397   }
398 
399   if (ReverseView) {
400     tempPosition.z*=-1.0;
401   }
402 
403   if (tempPosition.z > 0.0) {
404     return;
405   }
406 
407   // Check if point is within radar
408   if (tempPosition.x < 3.0 && tempPosition.x > -3.0 &&
409       tempPosition.y < -3.0 && tempPosition.y > -7.0) {
410     return;
411   }
412 
413   glBegin(GL_POINTS);
414   glColor3f(PointColor->red, PointColor->green, PointColor->blue);
415   glVertex3f(tempPosition.x, tempPosition.y, tempPosition.z);
416   glEnd();
417 }
418 
419 
420 /*
421   Function to draw text on the screen, it returns the x position after the text
422   is drawn.
423 */
DrawText(int xpos,int ypos,char * text,struct Color * TextColor,int big=0)424 int DrawText(int xpos, int ypos, char *text, struct Color *TextColor, int big=0)
425 {
426   float x, y;
427   float CharWidth;
428 
429   x=xpos;
430   y=ypos;
431 
432   x=(x/ScreenWidth)*2.0-1.0;
433   y=(y/ScreenHeight)*2.0-1.0;
434 
435   glColor3f(TextColor->red, TextColor->green, TextColor->blue);
436   while (*text) {
437     glRasterPos2f(x, y);
438     if (big) {
439 #ifndef CYGWIN
440       glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *text);
441       CharWidth=glutBitmapWidth(GLUT_BITMAP_HELVETICA_18, *text);
442 #else
443       glutBitmapCharacter((void *)8, *text);
444       CharWidth=glutBitmapWidth((void *)8, *text);
445 #endif
446     } else {
447 #ifndef CYGWIN
448       glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *text);
449       CharWidth=glutBitmapWidth(GLUT_BITMAP_HELVETICA_10, *text);
450 #else
451       glutBitmapCharacter((void *)6, *text);
452       CharWidth=glutBitmapWidth((void *)6, *text);
453 #endif
454     }
455     x+=(CharWidth/ScreenWidth)*2.0;
456     xpos+=(int)CharWidth;
457     text++;
458   }
459   return(xpos);
460 }
461 
462 
463 // Function to draw a rectangle on the screen
DrawRect(int x1pos,int y1pos,int x2pos,int y2pos,int x3pos,int y3pos,int x4pos,int y4pos,struct Color * LineColor)464 void DrawRect(int x1pos, int y1pos, int x2pos, int y2pos,
465               int x3pos, int y3pos, int x4pos, int y4pos,
466               struct Color *LineColor)
467 {
468   float x1, y1, x2, y2, x3, y3, x4, y4;
469 
470   x1=x1pos;
471   y1=y1pos;
472   x2=x2pos;
473   y2=y2pos;
474   x3=x3pos;
475   y3=y3pos;
476   x4=x4pos;
477   y4=y4pos;
478 
479   x1=(x1/ScreenWidth)*2.0-1.0;
480   y1=(y1/ScreenHeight)*2.0-1.0;
481   x2=(x2/ScreenWidth)*2.0-1.0;
482   y2=(y2/ScreenHeight)*2.0-1.0;
483   x3=(x3/ScreenWidth)*2.0-1.0;
484   y3=(y3/ScreenHeight)*2.0-1.0;
485   x4=(x4/ScreenWidth)*2.0-1.0;
486   y4=(y4/ScreenHeight)*2.0-1.0;
487 
488   glBegin(GL_QUADS);
489   glColor3f(LineColor->red, LineColor->green, LineColor->blue);
490   glVertex2f(x1, y1);
491   glVertex2f(x2, y2);
492   glVertex2f(x3, y3);
493   glVertex2f(x4, y4);
494   glEnd();
495 }
496 
497 
498 // Function to initialize the screen and setup keyboard callbacks
InitScreen()499 void InitScreen()
500 {
501   GLenum type;
502   char TextureFileName[1000];
503 
504   MainMenuItemHighlighted=0;
505   ConfMenuItemHighlighted=15;
506   ScoreMenuItemHighlighted=1;
507   NewScreenWidth=ScreenWidth;
508   NewScreenHeight=ScreenHeight;
509 
510   type = GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE;
511   glutInitDisplayMode(type);
512   glutInitWindowSize(ScreenWidth, ScreenHeight);
513   glutCreateWindow("Avoid The Roid");
514   glutIgnoreKeyRepeat(1);
515   glutSpecialFunc(MainMenuSpecialKey);
516   glutKeyboardFunc(MainMenuKey);
517   glutIdleFunc(NULL);
518   glutDisplayFunc(MainMenu);
519   glClearColor(0, 0, 0, 0);
520   glColor3f(1, 1, 1);
521   glGenTextures(1, texture);
522 #ifdef WINDOWS
523   sprintf(TextureFileName, "textures/explosion.rgb");
524 #else
525   sprintf(TextureFileName, "%s/atr3d/textures/explosion.rgb", DATADIR);
526 #endif
527   LoadTexture(TextureFileName);
528   glEnable(GL_DEPTH_TEST);
529 }
530 
531 
StartGame()532 void StartGame()
533 {
534   glutMainLoop();
535 }
536 
537 
ClearScreen()538 void ClearScreen()
539 {
540   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
541   glDisable(GL_LIGHT1);
542 }
543 
544 
Setup3dMode()545 void Setup3dMode()
546 {
547   glClearColor(0.0, 0.0, 0.0, 0.0);
548   glShadeModel(GL_SMOOTH);
549   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
550   glLoadIdentity();
551 }
552 
553 
554 
UpdateScreen()555 void UpdateScreen()
556 {
557   glutSwapBuffers();
558 }
559 
560 
InitColors()561 void InitColors()
562 {
563   White.red=1.0;
564   White.green=1.0;
565   White.blue=1.0;
566 
567   Black.red=0.0;
568   Black.green=0.0;
569   Black.blue=0.0;
570 
571   Red.red=1.0;
572   Red.green=0.0;
573   Red.blue=0.0;
574 
575   DarkRed.red=0.7;
576   DarkRed.green=0.0;
577   DarkRed.blue=0.0;
578 
579   Green.red=0.0;
580   Green.green=1.0;
581   Green.blue=0.0;
582 
583   Blue.red=0.0;
584   Blue.green=0.0;
585   Blue.blue=1.0;
586 
587   LightGray.red=0.7;
588   LightGray.green=0.7;
589   LightGray.blue=0.7;
590 
591   Gray.red=0.45;
592   Gray.green=0.45;
593   Gray.blue=0.45;
594 
595   DarkGray.red=0.2;
596   DarkGray.green=0.2;
597   DarkGray.blue=0.2;
598 }
599 
600 
DrawTriangle(struct Point * point1,struct Point * point2,struct Point * point3,struct Color * Point1Color,struct Color * Point2Color,struct Color * Point3Color)601 void DrawTriangle(struct Point *point1, struct Point *point2,
602                   struct Point *point3, struct Color *Point1Color,
603                   struct Color *Point2Color, struct Color *Point3Color)
604 {
605   if (ReverseView) {
606     point1->z*=-1.0;
607     point2->z*=-1.0;
608     point3->z*=-1.0;
609   }
610 
611   glBegin(GL_TRIANGLES);
612   glColor3f(Point1Color->red, Point1Color->green, Point1Color->blue);
613   glVertex3f(point1->x, point1->y, point1->z);
614   glColor3f(Point2Color->red, Point2Color->green, Point2Color->blue);
615   glVertex3f(point2->x, point2->y, point2->z);
616   glColor3f(Point3Color->red, Point3Color->green, Point3Color->blue);
617   glVertex3f(point3->x, point3->y, point3->z);
618   glEnd();
619 }
620 
621 
CalcPosition(struct Point * Position,struct Point * newPosition)622 void CalcPosition(struct Point *Position, struct Point *newPosition)
623 {
624   newPosition->x=Position->x-Ships[myShip]->Position.x;
625   newPosition->y=Position->y-Ships[myShip]->Position.y;
626   newPosition->z=Position->z-Ships[myShip]->Position.z;
627 
628   if (newPosition->x > WorldWidth) {
629     newPosition->x-=WorldWidth*2.0;
630   }
631   if (newPosition->y > WorldWidth) {
632     newPosition->y-=WorldWidth*2.0;
633   }
634   if (newPosition->z > WorldWidth) {
635     newPosition->z-=WorldWidth*2.0;
636   }
637   if (newPosition->x < -WorldWidth) {
638     newPosition->x+=WorldWidth*2.0;
639   }
640   if (newPosition->y < -WorldWidth) {
641     newPosition->y+=WorldWidth*2.0;
642   }
643   if (newPosition->z < -WorldWidth) {
644     newPosition->z+=WorldWidth*2.0;
645   }
646 }
647 
648 
CalcPoint(struct Point * point,struct Point * newpoint)649 void CalcPoint(struct Point *point, struct Point *newpoint)
650 {
651   struct Point tmpPoint;
652 
653   CalcPosition(point, &tmpPoint);
654 
655   newpoint->x=Ships[myShip]->CameraMatrix[0][0]*tmpPoint.x+Ships[myShip]->CameraMatrix[0][1]*tmpPoint.y+Ships[myShip]->CameraMatrix[0][2]*tmpPoint.z;
656   newpoint->y=Ships[myShip]->CameraMatrix[1][0]*tmpPoint.x+Ships[myShip]->CameraMatrix[1][1]*tmpPoint.y+Ships[myShip]->CameraMatrix[1][2]*tmpPoint.z;
657   newpoint->z=Ships[myShip]->CameraMatrix[2][0]*tmpPoint.x+Ships[myShip]->CameraMatrix[2][1]*tmpPoint.y+Ships[myShip]->CameraMatrix[2][2]*tmpPoint.z;
658 }
659 
660 
CalcPointWithRotation(struct Point * point,struct Point * newpoint,struct Point * Position,float RotationMatrix[3][3],float Size)661 void CalcPointWithRotation(struct Point *point, struct Point *newpoint,
662                            struct Point *Position, float RotationMatrix[3][3],
663                            float Size)
664 {
665   struct Point tmpPoint;
666 
667   tmpPoint.x=RotationMatrix[0][0]*point->x+RotationMatrix[0][1]*point->y+RotationMatrix[0][2]*point->z;
668   tmpPoint.y=RotationMatrix[1][0]*point->x+RotationMatrix[1][1]*point->y+RotationMatrix[1][2]*point->z;
669   tmpPoint.z=RotationMatrix[2][0]*point->x+RotationMatrix[2][1]*point->y+RotationMatrix[2][2]*point->z;
670 
671   tmpPoint.x*=Size;
672   tmpPoint.y*=Size;
673   tmpPoint.z*=Size;
674 
675   tmpPoint.x+=Position->x;
676   tmpPoint.y+=Position->y;
677   tmpPoint.z+=Position->z;
678 
679   newpoint->x=Ships[myShip]->CameraMatrix[0][0]*tmpPoint.x+Ships[myShip]->CameraMatrix[0][1]*tmpPoint.y+Ships[myShip]->CameraMatrix[0][2]*tmpPoint.z;
680   newpoint->y=Ships[myShip]->CameraMatrix[1][0]*tmpPoint.x+Ships[myShip]->CameraMatrix[1][1]*tmpPoint.y+Ships[myShip]->CameraMatrix[1][2]*tmpPoint.z;
681   newpoint->z=Ships[myShip]->CameraMatrix[2][0]*tmpPoint.x+Ships[myShip]->CameraMatrix[2][1]*tmpPoint.y+Ships[myShip]->CameraMatrix[2][2]*tmpPoint.z;
682 }
683 
684 
CalcPointWithRotation(struct Point * point)685 void CalcPointWithRotation(struct Point *point)
686 {
687   struct Point tmpPoint;
688 
689   tmpPoint.x=point->x;
690   tmpPoint.y=point->y;
691   tmpPoint.z=point->z;
692 
693   point->x=Ships[myShip]->CameraMatrix[0][0]*tmpPoint.x+Ships[myShip]->CameraMatrix[0][1]*tmpPoint.y+Ships[myShip]->CameraMatrix[0][2]*tmpPoint.z;
694   point->y=Ships[myShip]->CameraMatrix[1][0]*tmpPoint.x+Ships[myShip]->CameraMatrix[1][1]*tmpPoint.y+Ships[myShip]->CameraMatrix[1][2]*tmpPoint.z;
695   point->z=Ships[myShip]->CameraMatrix[2][0]*tmpPoint.x+Ships[myShip]->CameraMatrix[2][1]*tmpPoint.y+Ships[myShip]->CameraMatrix[2][2]*tmpPoint.z;
696 }
697 
698 
CalcRotation(struct Point * point,struct Point * newpoint,float RotationMatrix[3][3])699 void CalcRotation(struct Point *point, struct Point *newpoint,
700                   float RotationMatrix[3][3])
701 {
702   newpoint->x=RotationMatrix[0][0]*point->x+RotationMatrix[0][1]*point->y+RotationMatrix[0][2]*point->z;
703   newpoint->y=RotationMatrix[1][0]*point->x+RotationMatrix[1][1]*point->y+RotationMatrix[1][2]*point->z;
704   newpoint->z=RotationMatrix[2][0]*point->x+RotationMatrix[2][1]*point->y+RotationMatrix[2][2]*point->z;
705 }
706 
707 
DrawPowerup(Object * Obj)708 void DrawPowerup(Object *Obj)
709 {
710   struct Triangle *tempModel;
711   struct Point newPosition;
712   struct Point testPosition;
713   struct Point tempPoints[3];
714   int i, j;
715 
716   CalcPosition(&Obj->Position, &newPosition);
717 
718   // Check if object is behind the player, if so don't draw
719   memcpy(&testPosition, &newPosition, sizeof(struct Point));
720   CalcPointWithRotation(&testPosition);
721 
722   if (ReverseView) {
723     testPosition.z*=-1.0;
724   }
725 
726   if (testPosition.z > 0.0) {
727     return;
728   }
729 
730   if (ReverseView) {
731     testPosition.z*=-1.0;
732   }
733 
734   for (i=0; i<Obj->ObjModel->NumSides; i++) {
735     for (j=0; j<3; j++) {
736       tempPoints[j].x=testPosition.x+Obj->ObjModel->Sides[i].Vertices[j]->x*Obj->Size;
737       tempPoints[j].y=testPosition.y+Obj->ObjModel->Sides[i].Vertices[j]->y*Obj->Size;
738       tempPoints[j].z=testPosition.z+Obj->ObjModel->Sides[i].Vertices[j]->z*Obj->Size;
739     }
740 
741     DrawTriangle(&tempPoints[0], &tempPoints[1], &tempPoints[2],
742                  Obj->ObjModel->Sides[i].VertexColors[0],
743                  Obj->ObjModel->Sides[i].VertexColors[1],
744                  Obj->ObjModel->Sides[i].VertexColors[2]);
745   }
746 }
747 
748 
DrawObject(Object * Obj)749 void DrawObject(Object *Obj)
750 {
751   struct Triangle *tempModel;
752   struct Point newPosition;
753   struct Point testPosition;
754   struct Point tempPoints[3];
755   int i, j;
756 
757   CalcPosition(&Obj->Position, &newPosition);
758 
759   // Check if object is behind the player, if so don't draw
760   memcpy(&testPosition, &newPosition, sizeof(struct Point));
761   CalcPointWithRotation(&testPosition);
762   if (ReverseView) {
763     testPosition.z*=-1.0;
764   }
765 
766   if (testPosition.z > 0.0) {
767     return;
768   }
769 
770   for (i=0; i<Obj->ObjModel->NumSides; i++) {
771     for (j=0; j<3; j++) {
772       CalcPointWithRotation(Obj->ObjModel->Sides[i].Vertices[j],
773                             &tempPoints[j], &newPosition,
774                             Obj->RotationMatrix, Obj->Size);
775     }
776 
777     DrawTriangle(&tempPoints[0], &tempPoints[1], &tempPoints[2],
778                  Obj->ObjModel->Sides[i].VertexColors[0],
779                  Obj->ObjModel->Sides[i].VertexColors[1],
780                  Obj->ObjModel->Sides[i].VertexColors[2]);
781   }
782 }
783 
784 
LoadTexture(char * fn)785 void LoadTexture(char *fn)
786 {
787   int texwid, texht;
788   int texcomps;
789   unsigned *teximage;
790 
791   teximage = read_texture(fn, &texwid, &texht, &texcomps);
792   if (!teximage) {
793     printf("Sorry, can't read texture file...");
794     exit(0);
795   }
796   glBindTexture(GL_TEXTURE_2D, texture[0]);
797   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
798   glTexImage2D(GL_TEXTURE_2D, 0, 3, texwid, texht, 0, GL_RGBA, GL_UNSIGNED_BYTE, teximage);
799   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texwid, texht, GL_RGBA, GL_UNSIGNED_BYTE, teximage);
800 
801   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
802   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
803 
804   free(teximage);
805 }
806 
807 
EnableTransparency()808 void EnableTransparency()
809 {
810   glEnable(GL_BLEND);
811   glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
812 }
813 
814 
DisableTransparency()815 void DisableTransparency()
816 {
817   glDisable(GL_BLEND);
818 }
819 
820 
InitMatrixMode()821 void InitMatrixMode()
822 {
823   glMatrixMode(GL_PROJECTION);
824   glLoadIdentity();
825 }
826 
827 
SetupGameMatrixMode()828 void SetupGameMatrixMode()
829 {
830   float Ratio;
831 
832   Ratio=(float)ScreenWidth/(float)ScreenHeight;
833   gluPerspective(60.0, Ratio, 0.1, 20.0);
834   glMatrixMode(GL_MODELVIEW);
835 }
836