1 /**************************************************************************
2 * panel.cxx -- routines to draw an instrument panel
4 * Written by Friedemann Reinhard, started June 1998.
6 * Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
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.
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.
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.
23 * (Log is kept at end of this file)
24 **************************************************************************/
43 #include <Aircraft/aircraft.h>
44 #include <Debug/fg_debug.h>
45 #include <Main/options.hxx>
49 // Intriquing. Needs documentation.
52 #define IMAGIC_SWAP 0xda01
54 #define SWAP_SHORT_BYTES(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
55 #define SWAP_LONG_BYTES(x) (((((x) & 0xff) << 24) | (((x) & 0xff00) << 8)) | \
56 ((((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)))
59 unsigned short imagic;
62 unsigned short sizeX, sizeY, sizeZ;
63 unsigned long min, max;
64 unsigned long wasteBytes;
66 unsigned long colorMap;
68 unsigned char *tmp[5];
70 unsigned long *rowStart;
71 unsigned long *rowSize;
77 static GLuint panel_list;
78 static GLuint panel_tex_id;
79 static GLubyte tex[512][256][4];
82 extern double get_speed( void );
85 /* image.c ,temporary hack, I know*/
86 static Image *ImageOpen(char *fileName)
89 unsigned long *rowStart, *rowSize, ulTmp;
92 image = (Image *)malloc(sizeof(Image));
95 fprintf(stderr, "Out of memory!\n");
98 if ((image->file = fopen(fileName, "rb")) == NULL)
104 * Read the image header
106 fread(image, 1, 12, image->file);
110 if (image->imagic == IMAGIC_SWAP)
112 image->type = SWAP_SHORT_BYTES(image->type);
113 image->dim = SWAP_SHORT_BYTES(image->dim);
114 image->sizeX = SWAP_SHORT_BYTES(image->sizeX);
115 image->sizeY = SWAP_SHORT_BYTES(image->sizeY);
116 image->sizeZ = SWAP_SHORT_BYTES(image->sizeZ);
119 for ( i = 0 ; i <= image->sizeZ ; i++ )
121 image->tmp[i] = (unsigned char *)malloc(image->sizeX*256);
122 if (image->tmp[i] == NULL )
124 fprintf(stderr, "Out of memory!\n");
129 if ((image->type & 0xFF00) == 0x0100) /* RLE image */
131 x = image->sizeY * image->sizeZ * sizeof(long);
132 image->rowStart = (unsigned long *)malloc(x);
133 image->rowSize = (unsigned long *)malloc(x);
134 if (image->rowStart == NULL || image->rowSize == NULL)
136 fprintf(stderr, "Out of memory!\n");
139 image->rleEnd = 512 + (2 * x);
140 fseek(image->file, 512, SEEK_SET);
141 fread(image->rowStart, 1, x, image->file);
142 fread(image->rowSize, 1, x, image->file);
143 if (image->imagic == IMAGIC_SWAP)
146 rowStart = image->rowStart;
147 rowSize = image->rowSize;
151 *rowStart++ = SWAP_LONG_BYTES(ulTmp);
153 *rowSize++ = SWAP_LONG_BYTES(ulTmp);
160 static void ImageClose( Image *image)
165 for ( i = 0 ; i <= image->sizeZ ; i++ )
170 static void ImageGetRow( Image *image, unsigned char *buf, int y, int z)
172 unsigned char *iPtr, *oPtr, pixel;
175 if ((image->type & 0xFF00) == 0x0100) /* RLE image */
177 fseek(image->file, image->rowStart[y+z*image->sizeY], SEEK_SET);
178 fread(image->tmp[0], 1, (unsigned int)image->rowSize[y+z*image->sizeY],
181 iPtr = image->tmp[0];
186 count = (int)(pixel & 0x7F);
206 else /* verbatim image */
208 fseek(image->file, 512+(y*image->sizeX)+(z*image->sizeX*image->sizeY),
210 fread(buf, 1, image->sizeX, image->file);
214 static void ImageGetRawData( Image *image, unsigned char *data)
219 switch ( image->sizeZ )
222 remain = image->sizeX % 4;
225 remain = image->sizeX % 2;
228 remain = (image->sizeX * 3) & 0x3;
237 for (i = 0; i < image->sizeY; i++)
239 for ( k = 0; k < image->sizeZ ; k++ )
240 ImageGetRow(image, image->tmp[k+1], i, k);
241 for (j = 0; j < image->sizeX; j++)
242 for ( k = 1; k <= image->sizeZ ; k++ )
243 *data++ = *(image->tmp[k] + j);
248 static IMAGE *ImageLoad(char *fileName)
254 image = ImageOpen(fileName);
256 final = (IMAGE *)malloc(sizeof(IMAGE));
259 fprintf(stderr, "Out of memory!\n");
262 final->imagic = image->imagic;
263 final->type = image->type;
264 final->dim = image->dim;
265 final->sizeX = image->sizeX;
266 final->sizeY = image->sizeY;
267 final->sizeZ = image->sizeZ;
270 * Round up so rows are long-word aligned
272 sx = ( (image->sizeX) * (image->sizeZ) + 3) >> 2;
275 = (unsigned char *)malloc( sx * image->sizeY * sizeof(unsigned int));
277 if (final->data == NULL)
279 fprintf(stderr, "Out of memory!\n");
283 ImageGetRawData(image, final->data);
289 void fgPanelInit ( void ) {
293 #ifdef GL_VERSION_1_1
294 xglGenTextures(1, &panel_tex_id);
295 xglBindTexture(GL_TEXTURE_2D, panel_tex_id);
296 #elif GL_EXT_texture_object
297 xglGenTexturesEXT(1, &panel_tex_id);
298 xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id);
303 // xglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
304 xglPixelStorei(GL_UNPACK_ROW_LENGTH, 512);
305 xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
306 xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
307 xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
308 xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
310 /* load in the texture data */
311 tpath = current_options.get_fg_root() + "/Textures/panel1.rgb";
313 if ( (img = ImageLoad((char *)tpath.c_str()) ) == NULL ){
314 fgPrintf( FG_COCKPIT, FG_EXIT,
315 "Error loading cockpit texture %s\n", tpath.c_str() );
318 for ( y = 0; y < 256; y++ ) {
319 for ( x = 0; x < 512; x++ ) {
320 tex[x][y][0]=img->data[(y+x*256)*3];
321 tex[x][y][1]=img->data[(y+x*256)*3+1];
322 tex[x][y][2]=img->data[(y+x*256)*3+2];
323 if ( (tex[x][y][0] == 0) && (tex[x][y][1] == 0) &&
324 (tex[x][y][2] == 0) ) {
331 xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 256, 0, GL_RGBA,
332 GL_UNSIGNED_BYTE, (GLvoid *)(tex));
333 xglPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
335 printf("ALPHA=%d\n", tex[0][0][3]);
336 printf("ALPHA=%d\n", tex[512][0][3]);
337 printf("ALPHA=%d\n", tex[512][256][3]);
338 printf("ALPHA=%d\n", tex[0][256][3]);
340 panel_list = xglGenLists (1);
341 xglNewList(panel_list, GL_COMPILE);
342 xglBegin(GL_POLYGON);
343 xglTexCoord2f(0.0,0.0); glVertex2f(0.0,0.0);
344 xglTexCoord2f(1.0,0.0); glVertex2f(640.0,0.0);
345 xglTexCoord2f(1.0,1.0); glVertex2f(640.0,330.0);
346 // xglTexCoord2f(0.6,1.0); glVertex2f(384.0,330.0);
347 // xglTexCoord2f(0.166666,0.91111); glVertex2f(106.66666,303.182);
348 // xglTexCoord2f(0.0, 0.75769231); glVertex2f(0.0, 279.61);
349 xglTexCoord2f(0.0,1.0); glVertex2f(0.0,330.0);
355 void fgPanelUpdate ( void ) {
359 xglMatrixMode(GL_PROJECTION);
362 // xglViewport(0, 0, 640, 480);
363 gluOrtho2D(0, 640, 0, 480);
364 xglMatrixMode(GL_MODELVIEW);
368 xglDisable(GL_DEPTH_TEST);
369 xglDisable(GL_LIGHTING);
370 xglEnable(GL_TEXTURE_2D);
371 #ifdef GL_VERSION_1_1
372 xglBindTexture(GL_TEXTURE_2D, panel_tex_id);
373 #elif GL_EXT_texture_object
374 xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id);
379 xglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
380 xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_BLEND);
381 xglColor4f(1.0, 1.0, 1.0, 1.0);
383 xglCallList(panel_list);
386 xglDisable(GL_TEXTURE_2D);
388 alpha=((((float)(speed))/150)*270 + 20);
389 xglTranslatef(130, 146, 0);
390 xglRotatef(-alpha, 0.0, 0.0, 1.0);
391 xglScalef(20, 23, 0.0);
392 xglBegin(GL_POLYGON);
393 xglColor4f(1.0, 1.0, 1.0, 1.0);
394 xglVertex2f(0.0, 0.0);
395 xglVertex2f(0.1, 0.2);
396 xglVertex2f(0.0, 1.0);
397 xglVertex2f(-0.1, 0.2);
398 xglVertex2f(0.0, 0.0);
404 xglEnable(GL_DEPTH_TEST);
405 xglEnable(GL_LIGHTING);
406 xglDisable(GL_TEXTURE_2D);
407 xglDisable(GL_BLEND);
408 xglDisable(GL_ALPHA_TEST);
410 xglMatrixMode(GL_PROJECTION);
412 xglMatrixMode(GL_MODELVIEW);
418 /* Revision 1.5 1998/08/27 17:02:03 curt
419 /* Contributions from Bernie Bright <bbright@c031.aone.net.au>
420 /* - use strings for fg_root and airport_id and added methods to return
422 /* - inlined all access methods,
423 /* - made the parsing functions private methods,
424 /* - deleted some unused functions.
425 /* - propogated some of these changes out a bit further.
427 * Revision 1.4 1998/07/24 21:37:00 curt
428 * Ran dos2unix to get rid of extraneous ^M's. Tweaked parameter in
429 * ImageGetRawData() to match usage.
431 * Revision 1.3 1998/07/13 21:00:52 curt
432 * Integrated Charlies latest HUD updates.
433 * Wrote access functions for current fgOPTIONS.
435 * Revision 1.2 1998/07/03 11:55:37 curt
436 * A few small rearrangements and tweaks.
438 * Revision 1.1 1998/06/27 16:47:54 curt
439 * Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
440 * first pass at an isntrument panel.