#include #include #include #include #include "skyfly.h" void init_misc(void); void init_skyfly(void); void sim_singlechannel(void); void cull_proc(void); void draw_proc(void); #define SKY_R 0.23f #define SKY_G 0.35f #define SKY_B 0.78f #define TERR_DARK_R 0.27f #define TERR_DARK_G 0.18f #define TERR_DARK_B 0.00f #define TERR_LITE_R 0.24f #define TERR_LITE_G 0.53f #define TERR_LITE_B 0.05f typedef struct { unsigned char red; unsigned char green; unsigned char blue; } palette_t; palette_t pal[256]; static int buttons[BUTCOUNT] = { 0 }; static int mouse_x, mouse_y; GLboolean show_timer = GL_FALSE; GLboolean fullscreen = GL_TRUE; int Xgetbutton(int button) { int b; if (button < 0 || button >= BUTCOUNT) return -1; b = buttons[button]; if (button < LEFTMOUSE) buttons[button] = 0; return b; } int Xgetvaluator(int val) { switch (val) { case MOUSEX: return mouse_x; case MOUSEY: return mouse_y; default: return -1; } } void setPaletteIndex(int i, GLfloat r, GLfloat g, GLfloat b) { pal[i].red = (255.0F * r); pal[i].green = (255.0F * g); pal[i].blue = (255.0F * b); } void init_cmap(void) { int ii, jj, color; GLfloat r0, g0, b0, r1, g1, b1; /* Set up color map */ color = 10; memset(pal,0,sizeof(pal)); /* Sky colors */ sky_base = color; r0 = SKY_R; r1 = 1.0f; g0 = SKY_G; g1 = 1.0f; b0 = SKY_B; b1 = 1.0f; for (ii = 0; ii < SKY_COLORS; ii++) { GLfloat p, r, g, b; p = (GLfloat) ii / (SKY_COLORS-1); r = r0 + p * (r1 - r0); g = g0 + p * (g1 - g0); b = b0 + p * (b1 - b0); for (jj = 0; jj < FOG_LEVELS; jj++) { GLfloat fp, fr, fg, fb; fp = (FOG_LEVELS > 1) ? (GLfloat) jj / (FOG_LEVELS-1) : 0.0f; fr = r + fp * (fog_params[0] - r); fg = g + fp * (fog_params[1] - g); fb = b + fp * (fog_params[2] - b); setPaletteIndex(sky_base + (ii*FOG_LEVELS) + jj, fr, fg, fb); } } color += (SKY_COLORS * FOG_LEVELS); /* Terrain colors */ terr_base = color; r0 = TERR_DARK_R; r1 = TERR_LITE_R; g0 = TERR_DARK_G; g1 = TERR_LITE_G; b0 = TERR_DARK_B; b1 = TERR_LITE_B; for (ii = 0; ii < TERR_COLORS; ii++) { GLfloat p, r, g, b; p = (GLfloat) ii / (TERR_COLORS-1); r = r0 + p * (r1 - r0); g = g0 + p * (g1 - g0); b = b0 + p * (b1 - b0); for (jj = 0; jj < FOG_LEVELS; jj++) { GLfloat fp, fr, fg, fb; fp = (FOG_LEVELS > 1) ? (GLfloat) jj / (FOG_LEVELS-1) : 0.0f; fr = r + fp * (fog_params[0] - r); fg = g + fp * (fog_params[1] - g); fb = b + fp * (fog_params[2] - b); setPaletteIndex(terr_base + (ii*FOG_LEVELS) + jj, fr, fg, fb); } } color += (TERR_COLORS * FOG_LEVELS); /* Plane colors */ plane_colors[0] = color; plane_colors[1] = color + (PLANE_COLORS/2); plane_colors[2] = color + (PLANE_COLORS-1); r0 = 0.4; r1 = 0.8; g0 = 0.4; g1 = 0.8; b0 = 0.1; b1 = 0.1; for (ii = 0; ii < PLANE_COLORS; ii++) { GLfloat p, r, g, b; p = (GLfloat) ii / (PLANE_COLORS); r = r0 + p * (r1 - r0); g = g0 + p * (g1 - g0); b = b0 + p * (b1 - b0); setPaletteIndex(plane_colors[0] + ii, r, g, b); } color += PLANE_COLORS; #if 0 GM_setPalette(pal,256,0); GM_realizePalette(256,0,true); #endif } void draw(void); void gameLogic(void) { sim_singlechannel(); draw(); } /* When not visible, stop animating. Restart when visible again. */ static void visible(int vis) { if (vis == GLUT_VISIBLE) { glutIdleFunc(gameLogic); } else { glutIdleFunc(NULL); } } int lastCount; /* Timer count for last fps update */ int frameCount; /* Number of frames for timing */ int fpsRate; /* Current frames per second rate */ void draw(void) { int newCount; char buf[20]; int i, len; /* Draw the frame */ cull_proc(); draw_proc(); /* Update the frames per second count if we have gone past at least a quarter of a second since the last update. */ newCount = glutGet(GLUT_ELAPSED_TIME); frameCount++; if ((newCount - lastCount) > 1000) { fpsRate = (int) ((10000.0f / (newCount - lastCount)) * frameCount); lastCount = newCount; frameCount = 0; } if (show_timer) { sprintf(buf,"%3d.%d fps", fpsRate / 10, fpsRate % 10); glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glDisable(GL_FOG); glDisable(GL_BLEND); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, Wxsize, 0, Wysize, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor3f(1.0f, 1.0f, 0.0f); glRasterPos2i(10, 10); len = strlen(buf); for (i = 0; i < len; i++) glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, buf[i]); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); } glutSwapBuffers(); } void reshape(int width, int height) { Wxsize = width; Wysize = height; mouse_x = Wxsize/2; mouse_y = Wysize/2; glViewport(0, 0, width, height); } /* ARGSUSED1 */ void keyboard(unsigned char c, int x, int y) { switch (c) { case 0x1B: exit(0); break; case 'r': buttons[RKEY] = 1; break; case '.': buttons[PERIODKEY] = 1; break; case ' ': buttons[SPACEKEY] = 1; break; case 'f': set_fog(!fog); break; case 'd': set_dither(!dither); break; case 't': show_timer = !show_timer; break; } } void mouse(int button, int state, int x, int y) { mouse_x = x; mouse_y = y; switch (button) { case GLUT_LEFT_BUTTON: buttons[LEFTMOUSE] = (state == GLUT_DOWN); break; case GLUT_MIDDLE_BUTTON: buttons[MIDDLEMOUSE] = (state == GLUT_DOWN); break; case GLUT_RIGHT_BUTTON: buttons[RIGHTMOUSE] = (state == GLUT_DOWN); break; } } void motion(int x, int y) { mouse_x = x; mouse_y = y; } /* ARGSUSED1 */ void special(int key, int x, int y) { switch (key) { case GLUT_KEY_LEFT: buttons[LEFTARROWKEY] = 1; break; case GLUT_KEY_UP: buttons[UPARROWKEY] = 1; break; case GLUT_KEY_RIGHT: buttons[RIGHTARROWKEY] = 1; break; case GLUT_KEY_DOWN: buttons[DOWNARROWKEY] = 1; break; case GLUT_KEY_PAGE_UP: buttons[PAGEUPKEY] = 1; break; case GLUT_KEY_PAGE_DOWN: buttons[PAGEDOWNKEY] = 1; break; } } int main(int argc, char **argv) { glutInit(&argc, argv); if (argc > 1 && !strcmp(argv[1], "-w")) fullscreen = GL_FALSE; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); if (fullscreen) { glutGameModeString("640x480:16@60"); glutEnterGameMode(); } else { glutInitWindowSize(400, 400); glutCreateWindow("GLUT-based OpenGL skyfly"); } glutDisplayFunc(draw); glutReshapeFunc(reshape); glutVisibilityFunc(visible); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); glutMotionFunc(motion); glutPassiveMotionFunc(motion); glutSpecialFunc(special); init_misc(); if (!rgbmode) init_cmap(); init_skyfly(); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }