/**************************************************************************
- * cockpit.c -- routines to draw a cockpit (initial draft)
+ * cockpit.cxx -- routines to draw a cockpit (initial draft)
*
* Written by Michele America, started September 1997.
*
#endif
#include <GL/glut.h>
+#include <XGL/xgl.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
#include <Aircraft/aircraft.h>
#include <Debug/fg_debug.h>
bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
{
- fgPrintf( FG_COCKPIT, FG_INFO, "Initializing cockpit subsystem\n");
-
-// cockpit->code = 1; /* It will be aircraft dependent */
-// cockpit->status = 0;
+ fgPrintf( FG_COCKPIT, FG_INFO, "Initializing cockpit subsystem\n");
+
+ // cockpit->code = 1; /* It will be aircraft dependent */
+ // cockpit->status = 0;
+
+ // If aircraft has HUD specified we will get the specs from its def
+ // file. For now we will depend upon hard coding in hud?
+
+ // We must insure that the existing instrument link is purged.
+ // This is done by deleting the links in the list.
+
+ // HI_Head is now a null pointer so we can generate a new list from the
+ // current aircraft.
+
+ fgHUDInit( cur_aircraft );
+ ac_cockpit = new fg_Cockpit();
+
+ fgPanelInit();
+
+ fgPrintf( FG_COCKPIT, FG_INFO,
+ " Code %d Status %d\n",
+ ac_cockpit->code(), ac_cockpit->status() );
+
+ return true;
+}
- // If aircraft has HUD specified we will get the specs from its def
- // file. For now we will depend upon hard coding in hud?
- // We must insure that the existing instrument link is purged.
- // This is done by deleting the links in the list.
+void fgCockpitUpdate( void ) {
+ fgOPTIONS *o;
+ fgVIEW *v;
- // HI_Head is now a null pointer so we can generate a new list from the
- // current aircraft.
+ o = ¤t_options;
+ v = ¤t_view;
- fgHUDInit( cur_aircraft );
- ac_cockpit = new fg_Cockpit();
+ fgPrintf( FG_COCKPIT, FG_DEBUG,
+ "Cockpit: code %d status %d\n",
+ ac_cockpit->code(), ac_cockpit->status() );
- fgPrintf( FG_COCKPIT, FG_INFO,
- " Code %d Status %d\n",
- ac_cockpit->code(), ac_cockpit->status() );
+ if ( o->hud_status ) {
+ // This will check the global hud linked list pointer.
+ // If these is anything to draw it will.
+ fgUpdateHUD();
+ }
- return true;
+ if ( o->panel_status && (fabs(v->view_offset) < 0.2) ) {
+ fgPanelUpdate();
+ }
}
-void fgCockpitUpdate( void )
-{
-
- fgPrintf( FG_COCKPIT, FG_DEBUG,
- "Cockpit: code %d status %d\n",
- ac_cockpit->code(), ac_cockpit->status() );
- fgUpdateHUD(); // This will check the global hud linked list pointer.
- // If these is anything to draw it will.
-}
/* $Log$
-/* Revision 1.8 1998/05/17 16:58:12 curt
-/* Added a View Frustum Culling ratio display to the hud.
+/* Revision 1.9 1998/06/27 16:47:53 curt
+/* Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
+/* first pass at an isntrument panel.
/*
+ * Revision 1.8 1998/05/17 16:58:12 curt
+ * Added a View Frustum Culling ratio display to the hud.
+ *
* Revision 1.7 1998/05/16 13:04:13 curt
* New updates from Charlie Hotchkiss.
*
--- /dev/null
+/**************************************************************************
+ * panel.cxx -- routines to draw an instrument panel
+ *
+ * Written by Friedemann Reinhard, started June 1998.
+ *
+ * Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ * (Log is kept at end of this file)
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif
+
+#include <GL/glut.h>
+#include <XGL/xgl.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <Aircraft/aircraft.h>
+#include <Debug/fg_debug.h>
+#include <Main/options.hxx>
+
+#include "panel.hxx"
+
+
+#define IMAGIC 0x01da
+#define IMAGIC_SWAP 0xda01
+
+#define SWAP_SHORT_BYTES(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+#define SWAP_LONG_BYTES(x) (((((x) & 0xff) << 24) | (((x) & 0xff00) << 8)) | \
+((((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)))
+
+typedef struct {
+ unsigned short imagic;
+ unsigned short type;
+ unsigned short dim;
+ unsigned short sizeX, sizeY, sizeZ;
+ unsigned long min, max;
+ unsigned long wasteBytes;
+ char name[80];
+ unsigned long colorMap;
+ FILE *file;
+ unsigned char *tmp[5];
+ unsigned long rleEnd;
+ unsigned long *rowStart;
+ unsigned long *rowSize;
+} Image;
+
+
+IMAGE *img;
+
+static GLuint panel_list;
+static GLuint panel_tex_id;
+static GLubyte tex[512][256][4];
+
+
+static double get_speed( void )
+{
+ fgFLIGHT *f;
+
+ f = current_aircraft.flight;
+ return( FG_V_equiv_kts ); // Make an explicit function call.
+}
+
+
+/* image.c ,temporary hack, I know*/
+static Image *ImageOpen(char *fileName)
+{
+ Image *image;
+ unsigned long *rowStart, *rowSize, ulTmp;
+ int x, i;
+
+ image = (Image *)malloc(sizeof(Image));
+ if (image == NULL)
+ {
+ fprintf(stderr, "Out of memory!\n");
+ exit(-1);
+ }
+ if ((image->file = fopen(fileName, "rb")) == NULL)
+ {
+ perror(fileName);
+ exit(-1);
+ }
+ /*
+ * Read the image header
+ */
+ fread(image, 1, 12, image->file);
+ /*
+ * Check byte order
+ */
+ if (image->imagic == IMAGIC_SWAP)
+ {
+ image->type = SWAP_SHORT_BYTES(image->type);
+ image->dim = SWAP_SHORT_BYTES(image->dim);
+ image->sizeX = SWAP_SHORT_BYTES(image->sizeX);
+ image->sizeY = SWAP_SHORT_BYTES(image->sizeY);
+ image->sizeZ = SWAP_SHORT_BYTES(image->sizeZ);
+ }
+
+ for ( i = 0 ; i <= image->sizeZ ; i++ )
+ {
+ image->tmp[i] = (unsigned char *)malloc(image->sizeX*256);
+ if (image->tmp[i] == NULL )
+ {
+ fprintf(stderr, "Out of memory!\n");
+ exit(-1);
+ }
+ }
+
+ if ((image->type & 0xFF00) == 0x0100) /* RLE image */
+ {
+ x = image->sizeY * image->sizeZ * sizeof(long);
+ image->rowStart = (unsigned long *)malloc(x);
+ image->rowSize = (unsigned long *)malloc(x);
+ if (image->rowStart == NULL || image->rowSize == NULL)
+ {
+ fprintf(stderr, "Out of memory!\n");
+ exit(-1);
+ }
+ image->rleEnd = 512 + (2 * x);
+ fseek(image->file, 512, SEEK_SET);
+ fread(image->rowStart, 1, x, image->file);
+ fread(image->rowSize, 1, x, image->file);
+ if (image->imagic == IMAGIC_SWAP)
+ {
+ x /= sizeof(long);
+ rowStart = image->rowStart;
+ rowSize = image->rowSize;
+ while (x--)
+ {
+ ulTmp = *rowStart;
+ *rowStart++ = SWAP_LONG_BYTES(ulTmp);
+ ulTmp = *rowSize;
+ *rowSize++ = SWAP_LONG_BYTES(ulTmp);
+ }
+ }
+ }
+ return image;
+}
+
+static void ImageClose( Image *image)
+{
+ int i;
+
+ fclose(image->file);
+ for ( i = 0 ; i <= image->sizeZ ; i++ )
+ free(image->tmp[i]);
+ free(image);
+}
+
+static void ImageGetRow( Image *image, unsigned char *buf, int y, int z)
+{
+ unsigned char *iPtr, *oPtr, pixel;
+ int count;
+
+ if ((image->type & 0xFF00) == 0x0100) /* RLE image */
+ {
+ fseek(image->file, image->rowStart[y+z*image->sizeY], SEEK_SET);
+ fread(image->tmp[0], 1, (unsigned int)image->rowSize[y+z*image->sizeY],
+ image->file);
+
+ iPtr = image->tmp[0];
+ oPtr = buf;
+ while (1)
+ {
+ pixel = *iPtr++;
+ count = (int)(pixel & 0x7F);
+ if (!count)
+ return;
+ if (pixel & 0x80)
+ {
+ while (count--)
+ {
+ *oPtr++ = *iPtr++;
+ }
+ }
+ else
+ {
+ pixel = *iPtr++;
+ while (count--)
+ {
+ *oPtr++ = pixel;
+ }
+ }
+ }
+ }
+ else /* verbatim image */
+ {
+ fseek(image->file, 512+(y*image->sizeX)+(z*image->sizeX*image->sizeY),
+ SEEK_SET);
+ fread(buf, 1, image->sizeX, image->file);
+ }
+}
+
+static void ImageGetRawData( Image *image, char *data)
+{
+ int i, j, k;
+ int remain;
+
+ switch ( image->sizeZ )
+ {
+ case 1:
+ remain = image->sizeX % 4;
+ break;
+ case 2:
+ remain = image->sizeX % 2;
+ break;
+ case 3:
+ remain = (image->sizeX * 3) & 0x3;
+ if (remain)
+ remain = 4 - remain;
+ break;
+ case 4:
+ remain = 0;
+ break;
+ }
+
+ for (i = 0; i < image->sizeY; i++)
+ {
+ for ( k = 0; k < image->sizeZ ; k++ )
+ ImageGetRow(image, image->tmp[k+1], i, k);
+ for (j = 0; j < image->sizeX; j++)
+ for ( k = 1; k <= image->sizeZ ; k++ )
+ *data++ = *(image->tmp[k] + j);
+ data += remain;
+ }
+}
+
+static IMAGE *ImageLoad(char *fileName)
+{
+ Image *image;
+ IMAGE *final;
+ int sx;
+
+ image = ImageOpen(fileName);
+
+ final = (IMAGE *)malloc(sizeof(IMAGE));
+ if (final == NULL)
+ {
+ fprintf(stderr, "Out of memory!\n");
+ exit(-1);
+ }
+ final->imagic = image->imagic;
+ final->type = image->type;
+ final->dim = image->dim;
+ final->sizeX = image->sizeX;
+ final->sizeY = image->sizeY;
+ final->sizeZ = image->sizeZ;
+
+ /*
+ * Round up so rows are long-word aligned
+ */
+ sx = ( (image->sizeX) * (image->sizeZ) + 3) >> 2;
+
+ final->data
+ = (unsigned char *)malloc( sx * image->sizeY * sizeof(unsigned int));
+
+ if (final->data == NULL)
+ {
+ fprintf(stderr, "Out of memory!\n");
+ exit(-1);
+ }
+
+ ImageGetRawData(image, final->data);
+ ImageClose(image);
+ return final;
+}
+
+
+void fgPanelInit ( void ) {
+ fgOPTIONS *o;
+ char tpath[256];
+ int x, y;
+
+ o = ¤t_options;
+
+#ifdef GL_VERSION_1_1
+ xglGenTextures(1, &panel_tex_id);
+ xglBindTexture(GL_TEXTURE_2D, panel_tex_id);
+#elif GL_EXT_texture_object
+ xglGenTexturesEXT(1, &panel_tex_id);
+ xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id);
+#else
+# error port me
+#endif
+
+ // glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 512);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ /* load in the texture data */
+ tpath[0] = '\0';
+ strcat(tpath, o->fg_root);
+ strcat(tpath, "/Textures/");
+ strcat(tpath, "panel1.rgb");
+
+ if ( (img = ImageLoad(tpath)) == NULL ){
+ fgPrintf( FG_COCKPIT, FG_EXIT,
+ "Error loading cockpit texture %s\n", tpath );
+ }
+
+ for ( y = 0; y < 256; y++ ) {
+ for ( x = 0; x < 512; x++ ) {
+ tex[x][y][0]=img->data[(y+x*256)*3];
+ tex[x][y][1]=img->data[(y+x*256)*3+1];
+ tex[x][y][2]=img->data[(y+x*256)*3+2];
+ if ( (tex[x][y][0] == 0) && (tex[x][y][1] == 0) &&
+ (tex[x][y][2] == 0) ) {
+ tex[x][y][3]=0;
+ } else {
+ tex[x][y][3]=255;
+ }
+ }
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 256, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, (GLvoid *)(tex));
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+ printf("ALPHA=%d\n", tex[0][0][3]);
+ printf("ALPHA=%d\n", tex[512][0][3]);
+ printf("ALPHA=%d\n", tex[512][256][3]);
+ printf("ALPHA=%d\n", tex[0][256][3]);
+
+ panel_list = glGenLists (1);
+ glNewList(panel_list, GL_COMPILE);
+ glBegin(GL_POLYGON);
+ glTexCoord2f(0.0,0.0); glVertex2f(0.0,0.0);
+ glTexCoord2f(1.0,0.0); glVertex2f(640.0,0.0);
+ glTexCoord2f(1.0,1.0); glVertex2f(640.0,330.0);
+ // glTexCoord2f(0.6,1.0); glVertex2f(384.0,330.0);
+ // glTexCoord2f(0.166666,0.91111); glVertex2f(106.66666,303.182);
+ // glTexCoord2f(0.0, 0.75769231); glVertex2f(0.0, 279.61);
+ glTexCoord2f(0.0,1.0); glVertex2f(0.0,330.0);
+ glEnd();
+ glEndList ();
+}
+
+
+void fgPanelUpdate ( void ) {
+ float alpha;
+ double speed;
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ //glViewport(0, 0, 640, 480);
+ gluOrtho2D(0, 640, 0, 480);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glEnable(GL_TEXTURE_2D);
+#ifdef GL_VERSION_1_1
+ xglBindTexture(GL_TEXTURE_2D, panel_tex_id);
+#elif GL_EXT_texture_object
+ xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id);
+#else
+# error port me
+#endif
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_BLEND);
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+
+ glCallList(panel_list);
+
+ glPushMatrix();
+ glDisable(GL_TEXTURE_2D);
+ speed = get_speed();
+ alpha=((((float)(speed))/150)*270 + 20);
+ glTranslatef(130, 146, 0);
+ glRotatef(-alpha, 0.0, 0.0, 1.0);
+ glScalef(20, 23, 0.0);
+ glBegin(GL_POLYGON);
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ glVertex2f(0.0, 0.0);
+ glVertex2f(0.1, 0.2);
+ glVertex2f(0.0, 1.0);
+ glVertex2f(-0.1, 0.2);
+ glVertex2f(0.0, 0.0);
+ glEnd();
+ glPopMatrix();
+
+ glFlush();
+
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_LIGHTING);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ glDisable(GL_ALPHA_TEST);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+}
+
+
+/* $Log$
+/* Revision 1.1 1998/06/27 16:47:54 curt
+/* Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
+/* first pass at an isntrument panel.
+/*
+ */