]> git.mxchange.org Git - flightgear.git/blob - Cockpit/panel.cxx
Ran dos2unix to get rid of extraneous ^M's. Tweaked parameter in
[flightgear.git] / Cockpit / panel.cxx
1 /**************************************************************************
2  * panel.cxx -- routines to draw an instrument panel
3  *
4  * Written by Friedemann Reinhard, started June 1998.
5  *
6  * Copyright (C) 1997  Michele F. America  - nomimarketing@mail.telepac.pt
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * $Id$
23  * (Log is kept at end of this file)
24  **************************************************************************/
25
26
27 #ifdef HAVE_CONFIG_H
28 #  include <config.h>
29 #endif
30
31 #ifdef HAVE_WINDOWS_H          
32 #  include <windows.h>
33 #endif
34
35 #include <GL/glut.h>
36 #include <XGL/xgl.h>
37
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41
42 #include <Aircraft/aircraft.h>
43 #include <Debug/fg_debug.h>
44 #include <Main/options.hxx>
45
46 #include "panel.hxx"
47
48   // Intriquing. Needs documentation.
49
50 #define IMAGIC      0x01da
51 #define IMAGIC_SWAP 0xda01
52
53 #define SWAP_SHORT_BYTES(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
54 #define SWAP_LONG_BYTES(x) (((((x) & 0xff) << 24) | (((x) & 0xff00) << 8)) | \
55 ((((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)))
56
57 typedef struct {
58     unsigned short imagic;
59     unsigned short type;
60     unsigned short dim;
61     unsigned short sizeX, sizeY, sizeZ;
62     unsigned long min, max;
63     unsigned long wasteBytes;
64     char name[80];
65     unsigned long colorMap;
66     FILE *file;
67     unsigned char *tmp[5];
68     unsigned long rleEnd;
69     unsigned long *rowStart;
70     unsigned long *rowSize;
71 } Image;
72
73
74 IMAGE *img;
75
76 static GLuint panel_list;
77 static GLuint panel_tex_id;
78 static GLubyte tex[512][256][4];
79
80
81 extern double get_speed( void );
82
83
84 /* image.c ,temporary hack, I know*/
85 static Image *ImageOpen(char *fileName)
86 {
87   Image *image;
88   unsigned long *rowStart, *rowSize, ulTmp;
89   int x, i;
90
91   image = (Image *)malloc(sizeof(Image));
92   if (image == NULL) 
93     {
94       fprintf(stderr, "Out of memory!\n");
95       exit(-1);
96     }
97   if ((image->file = fopen(fileName, "rb")) == NULL) 
98     {
99       perror(fileName);
100       exit(-1);
101     }
102   /*
103    *    Read the image header
104    */
105   fread(image, 1, 12, image->file);
106   /*
107    *    Check byte order
108    */
109   if (image->imagic == IMAGIC_SWAP) 
110     {
111       image->type = SWAP_SHORT_BYTES(image->type);
112       image->dim = SWAP_SHORT_BYTES(image->dim);
113       image->sizeX = SWAP_SHORT_BYTES(image->sizeX);
114       image->sizeY = SWAP_SHORT_BYTES(image->sizeY);
115       image->sizeZ = SWAP_SHORT_BYTES(image->sizeZ);
116     }
117
118   for ( i = 0 ; i <= image->sizeZ ; i++ )
119     {
120       image->tmp[i] = (unsigned char *)malloc(image->sizeX*256);
121       if (image->tmp[i] == NULL ) 
122         {
123           fprintf(stderr, "Out of memory!\n");
124           exit(-1);
125         }
126     }
127
128   if ((image->type & 0xFF00) == 0x0100) /* RLE image */
129     {
130       x = image->sizeY * image->sizeZ * sizeof(long);
131       image->rowStart = (unsigned long *)malloc(x);
132       image->rowSize = (unsigned long *)malloc(x);
133       if (image->rowStart == NULL || image->rowSize == NULL) 
134         {
135           fprintf(stderr, "Out of memory!\n");
136           exit(-1);
137         }
138       image->rleEnd = 512 + (2 * x);
139       fseek(image->file, 512, SEEK_SET);
140       fread(image->rowStart, 1, x, image->file);
141       fread(image->rowSize, 1, x, image->file);
142       if (image->imagic == IMAGIC_SWAP) 
143         {
144           x /= sizeof(long);
145           rowStart = image->rowStart;
146           rowSize = image->rowSize;
147           while (x--) 
148             {
149               ulTmp = *rowStart;
150               *rowStart++ = SWAP_LONG_BYTES(ulTmp);
151               ulTmp = *rowSize;
152               *rowSize++ = SWAP_LONG_BYTES(ulTmp);
153             }
154         }
155     }
156   return image;
157 }
158
159 static void ImageClose( Image *image)
160 {
161   int i;
162
163   fclose(image->file);
164   for ( i = 0 ; i <= image->sizeZ ; i++ )
165     free(image->tmp[i]);
166   free(image);
167 }
168
169 static void ImageGetRow( Image *image, unsigned char *buf, int y, int z)
170 {
171   unsigned char *iPtr, *oPtr, pixel;
172   int count;
173
174   if ((image->type & 0xFF00) == 0x0100)  /* RLE image */
175     {
176       fseek(image->file, image->rowStart[y+z*image->sizeY], SEEK_SET);
177       fread(image->tmp[0], 1, (unsigned int)image->rowSize[y+z*image->sizeY],
178             image->file);
179
180       iPtr = image->tmp[0];
181       oPtr = buf;
182       while (1) 
183         {
184           pixel = *iPtr++;
185           count = (int)(pixel & 0x7F);
186           if (!count)
187             return;
188           if (pixel & 0x80) 
189             {
190               while (count--) 
191                 {
192                   *oPtr++ = *iPtr++;
193                 }
194             } 
195           else 
196             {
197               pixel = *iPtr++;
198               while (count--) 
199                 {
200                   *oPtr++ = pixel;
201                 }
202             }
203         }
204     }
205   else /* verbatim image */
206     {
207       fseek(image->file, 512+(y*image->sizeX)+(z*image->sizeX*image->sizeY),
208             SEEK_SET);
209       fread(buf, 1, image->sizeX, image->file);
210     }
211 }
212
213 static void ImageGetRawData( Image *image, unsigned char *data)
214 {
215   int i, j, k;
216   int remain;
217
218   switch ( image->sizeZ )
219     {
220     case 1:
221       remain = image->sizeX % 4;
222       break;
223     case 2:
224       remain = image->sizeX % 2;
225       break;
226     case 3:
227       remain = (image->sizeX * 3) & 0x3;
228       if (remain)
229         remain = 4 - remain;
230       break;
231     case 4:
232       remain = 0;
233       break;
234     }
235
236   for (i = 0; i < image->sizeY; i++) 
237     {
238       for ( k = 0; k < image->sizeZ ; k++ )
239         ImageGetRow(image, image->tmp[k+1], i, k);
240       for (j = 0; j < image->sizeX; j++) 
241         for ( k = 1; k <= image->sizeZ ; k++ )
242           *data++ = *(image->tmp[k] + j);
243       data += remain;
244     }
245 }
246
247 static IMAGE *ImageLoad(char *fileName)
248 {
249   Image *image;
250   IMAGE *final;
251   int sx;
252
253   image = ImageOpen(fileName);
254
255   final = (IMAGE *)malloc(sizeof(IMAGE));
256   if (final == NULL) 
257     {
258       fprintf(stderr, "Out of memory!\n");
259       exit(-1);
260     }
261   final->imagic = image->imagic;
262   final->type = image->type;
263   final->dim = image->dim;
264   final->sizeX = image->sizeX; 
265   final->sizeY = image->sizeY;
266   final->sizeZ = image->sizeZ;
267
268   /* 
269    * Round up so rows are long-word aligned 
270    */
271   sx = ( (image->sizeX) * (image->sizeZ) + 3) >> 2;
272
273   final->data 
274     = (unsigned char *)malloc( sx * image->sizeY * sizeof(unsigned int));
275
276   if (final->data == NULL) 
277     {
278       fprintf(stderr, "Out of memory!\n");
279       exit(-1);
280     }
281
282   ImageGetRawData(image, final->data);
283   ImageClose(image);
284   return final;
285 }
286
287
288 void fgPanelInit ( void ) {
289     char tpath[256];
290     int x, y;
291
292 #ifdef GL_VERSION_1_1
293     xglGenTextures(1, &panel_tex_id);
294     xglBindTexture(GL_TEXTURE_2D, panel_tex_id);
295 #elif GL_EXT_texture_object
296     xglGenTexturesEXT(1, &panel_tex_id);
297     xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id);
298 #else
299 #  error port me
300 #endif
301
302     // xglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
303     xglPixelStorei(GL_UNPACK_ROW_LENGTH, 512);
304     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
305     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);   
306     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
307     xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
308
309     /* load in the texture data */
310     current_options.get_fg_root(tpath);
311     strcat(tpath, "/Textures/");
312     strcat(tpath, "panel1.rgb");
313
314     if ( (img = ImageLoad(tpath)) == NULL ){
315         fgPrintf( FG_COCKPIT, FG_EXIT, 
316                   "Error loading cockpit texture %s\n", tpath );
317     }
318
319     for ( y = 0; y < 256; y++ ) {
320         for ( x = 0; x < 512; x++ ) { 
321             tex[x][y][0]=img->data[(y+x*256)*3];
322             tex[x][y][1]=img->data[(y+x*256)*3+1];
323             tex[x][y][2]=img->data[(y+x*256)*3+2];
324             if ( (tex[x][y][0] == 0) && (tex[x][y][1] == 0) && 
325                  (tex[x][y][2] == 0) ) {
326                 tex[x][y][3]=0;
327             } else {
328                 tex[x][y][3]=255;
329             }
330         }
331     }
332     xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 256, 0, GL_RGBA, 
333                   GL_UNSIGNED_BYTE, (GLvoid *)(tex));
334     xglPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
335
336     printf("ALPHA=%d\n", tex[0][0][3]);
337     printf("ALPHA=%d\n", tex[512][0][3]);
338     printf("ALPHA=%d\n", tex[512][256][3]);
339     printf("ALPHA=%d\n", tex[0][256][3]);
340
341     panel_list = xglGenLists (1);
342     xglNewList(panel_list, GL_COMPILE);
343     xglBegin(GL_POLYGON);
344     xglTexCoord2f(0.0,0.0); glVertex2f(0.0,0.0);
345     xglTexCoord2f(1.0,0.0); glVertex2f(640.0,0.0);
346     xglTexCoord2f(1.0,1.0); glVertex2f(640.0,330.0);
347     // xglTexCoord2f(0.6,1.0); glVertex2f(384.0,330.0); 
348     // xglTexCoord2f(0.166666,0.91111); glVertex2f(106.66666,303.182);
349     // xglTexCoord2f(0.0, 0.75769231); glVertex2f(0.0, 279.61); 
350     xglTexCoord2f(0.0,1.0); glVertex2f(0.0,330.0); 
351     xglEnd();
352     xglEndList ();
353 }
354
355
356 void fgPanelUpdate ( void ) {
357     float alpha;
358     double speed;
359
360     xglMatrixMode(GL_PROJECTION);
361     xglPushMatrix();
362     xglLoadIdentity();
363     // xglViewport(0, 0, 640, 480);
364     gluOrtho2D(0, 640, 0, 480);
365     xglMatrixMode(GL_MODELVIEW);
366     xglPushMatrix();
367     xglLoadIdentity();
368
369     xglDisable(GL_DEPTH_TEST);
370     xglDisable(GL_LIGHTING);
371     xglEnable(GL_TEXTURE_2D);
372 #ifdef GL_VERSION_1_1
373     xglBindTexture(GL_TEXTURE_2D, panel_tex_id);
374 #elif GL_EXT_texture_object
375     xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id);
376 #else
377 #  error port me
378 #endif
379     xglEnable(GL_BLEND);
380     xglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
381     xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_BLEND);
382     xglColor4f(1.0, 1.0, 1.0, 1.0);
383
384     xglCallList(panel_list);
385
386     xglPushMatrix();
387     xglDisable(GL_TEXTURE_2D);
388     speed = get_speed();
389     alpha=((((float)(speed))/150)*270 + 20);
390     xglTranslatef(130, 146, 0);
391     xglRotatef(-alpha, 0.0, 0.0, 1.0);
392     xglScalef(20, 23, 0.0);
393     xglBegin(GL_POLYGON);
394     xglColor4f(1.0, 1.0, 1.0, 1.0);
395     xglVertex2f(0.0, 0.0);
396     xglVertex2f(0.1, 0.2);
397     xglVertex2f(0.0, 1.0);
398     xglVertex2f(-0.1, 0.2);
399     xglVertex2f(0.0, 0.0);
400     xglEnd();  
401     xglPopMatrix();   
402
403     // xglFlush();
404
405     xglEnable(GL_DEPTH_TEST);
406     xglEnable(GL_LIGHTING);
407     xglDisable(GL_TEXTURE_2D);
408     xglDisable(GL_BLEND);
409     xglDisable(GL_ALPHA_TEST);
410
411     xglMatrixMode(GL_PROJECTION);
412     xglPopMatrix();
413     xglMatrixMode(GL_MODELVIEW);
414     xglPopMatrix();
415 }
416
417
418 /* $Log$
419 /* Revision 1.4  1998/07/24 21:37:00  curt
420 /* Ran dos2unix to get rid of extraneous ^M's.  Tweaked parameter in
421 /* ImageGetRawData() to match usage.
422 /*
423  * Revision 1.3  1998/07/13 21:00:52  curt
424  * Integrated Charlies latest HUD updates.
425  * Wrote access functions for current fgOPTIONS.
426  *
427  * Revision 1.2  1998/07/03 11:55:37  curt
428  * A few small rearrangements and tweaks.
429  *
430  * Revision 1.1  1998/06/27 16:47:54  curt
431  * Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
432  * first pass at an isntrument panel.
433  *
434  */