#include #include #include #include #include #include #include #define TFV_PINK_TEXTURE 62 #define TOTAL_TEXTURES 63 /* As much as I have memorized... */ #define PI 3.141592653589793238462643383279502884197169399 #define D2R(x) ((x*PI*2.0)/360.0) static GLuint textures[TOTAL_TEXTURES]; #define UP_PRESSED 1 #define DOWN_PRESSED 2 #define LEFT_PRESSED 4 #define RIGHT_PRESSED 8 #define ACTION1_PRESSED 16 #define ACTION2_PRESSED 32 #define CONFIRM_PRESSED 64 #define CANCEL_PRESSED 128 #define PAN_LEFT_PRESSED 256 #define PAN_RIGHT_PRESSED 512 #define PAUSE_PRESSED 1024 #define MENU_PRESSED 2048 /* MODEL -> We pretend we essentially have essentially 10 buttons */ /* Right now this reflects the Gravis-Gamepad I have. Eventually */ /* I will add some sort of generic config utility for custom controls */ /* UP, DOWN, LEFT, RIGHT */ /* 1 (A or ACTION1) * 2 (Z or ACTION2) * 3 (ENTER or CONFIRM) * 4 (SPACE or CANCEL) * 5 (J or PAN_LEFT) * 6 (K or PAN_RIGHT) * 9 (P or PAUSE) *10 (ESCAPE or MENU) */ int check_keyboard(char *alphanum,int reset) { SDL_Event event; static int keys_down=0; int momentary=0; int button,axis,jdirection; int keypressed; *alphanum=0; if (reset) { keys_down=0; return 1; } while ( SDL_PollEvent(&event) ) { if ( event.type == SDL_QUIT ) { keys_down|=MENU_PRESSED; return 1; } if (event.type == SDL_VIDEORESIZE) { printf("RESIZE\b"); } if (event.type == SDL_JOYBUTTONDOWN) { button=event.jbutton.button; switch(button) { case 0: momentary|=ACTION1_PRESSED; keys_down|=ACTION1_PRESSED; break; case 1: momentary|=ACTION2_PRESSED; keys_down|=ACTION2_PRESSED; break; case 2: momentary|=CONFIRM_PRESSED; keys_down|=CONFIRM_PRESSED; break; case 3: momentary|=CANCEL_PRESSED; keys_down|=CANCEL_PRESSED; break; case 4: momentary|=PAN_LEFT_PRESSED; keys_down|=PAN_LEFT_PRESSED; break; case 5: momentary|=PAN_RIGHT_PRESSED; keys_down|=PAN_RIGHT_PRESSED; break; case 8: momentary|=PAUSE_PRESSED; keys_down|=PAUSE_PRESSED; break; case 9: momentary|=MENU_PRESSED; keys_down|=MENU_PRESSED; break; } //printf("Button: %i\n",button); } if (event.type == SDL_JOYAXISMOTION) { axis=event.jaxis.axis; jdirection=event.jaxis.value; if (axis==0) { /* X */ if (jdirection>20000) { keys_down|=RIGHT_PRESSED; } else if (jdirection<-20000) { keys_down|=LEFT_PRESSED; } else if ((jdirection>5000) || (jdirection<-5000)) { keys_down&=(~RIGHT_PRESSED); keys_down&=(~LEFT_PRESSED); // printf("X: %i\n",jdirection); } } if (axis==1) { /* Y */ if (jdirection>20000) { keys_down|=DOWN_PRESSED; } else if (jdirection<-20000) { keys_down|=UP_PRESSED; } else if ((jdirection>5000) || (jdirection<-5000)) { keys_down&=(~UP_PRESSED); keys_down&=(~DOWN_PRESSED); // printf("Y: %i\n",jdirection); } // printf("Y: %i\n",jdirection); } } if (event.type == SDL_JOYBUTTONUP) { button=event.jbutton.button; switch(button) { case 0: keys_down&=(~ACTION1_PRESSED); break; case 1: keys_down&=(~ACTION2_PRESSED); break; case 2: keys_down&=(~CONFIRM_PRESSED); break; case 3: keys_down&=(~CANCEL_PRESSED); break; case 4: keys_down&=(~PAN_LEFT_PRESSED); break; case 5: keys_down&=(~PAN_RIGHT_PRESSED); break; case 8: keys_down&=(~PAUSE_PRESSED); break; case 9: keys_down&=(~MENU_PRESSED); break; } //printf("Button: %i\n",button); } if (event.type == SDL_KEYUP) { keypressed=event.key.keysym.sym; switch(keypressed) { case SDLK_UP: keys_down&=(~UP_PRESSED); break; case SDLK_DOWN: keys_down&=(~DOWN_PRESSED); break; case SDLK_RIGHT: keys_down&=(~RIGHT_PRESSED); break; case SDLK_LEFT: keys_down&=(~LEFT_PRESSED); break; case SDLK_ESCAPE: keys_down&=(~MENU_PRESSED); break; case SDLK_RETURN: keys_down&=(~CONFIRM_PRESSED); break; case SDLK_SPACE: keys_down&=(~CANCEL_PRESSED); break; case 'a': case 'A': keys_down&=(~ACTION1_PRESSED); break; case 'z': case 'Z': keys_down&=(~ACTION2_PRESSED); break; case 'j': case 'J': keys_down&=(~PAN_LEFT_PRESSED); break; case 'k': case 'K': keys_down&=(~PAN_RIGHT_PRESSED); break; case 'p': case 'P': keys_down&=(~PAUSE_PRESSED); break; } } if ( event.type == SDL_KEYDOWN ) { keypressed=event.key.keysym.sym; switch (keypressed) { case 'a': case 'A': momentary|=ACTION1_PRESSED; keys_down|=ACTION1_PRESSED; break; case 'z': case 'Z': momentary|=ACTION2_PRESSED; keys_down|=ACTION2_PRESSED; break; case SDLK_RETURN: momentary|=CONFIRM_PRESSED; keys_down|=CONFIRM_PRESSED; break; case SDLK_SPACE: momentary|=CANCEL_PRESSED; keys_down|=CANCEL_PRESSED; break; case 'j': case 'J': momentary|=PAN_LEFT_PRESSED; keys_down|=PAN_LEFT_PRESSED; break; case 'k': case 'K': momentary|=PAN_RIGHT_PRESSED; keys_down|=PAN_RIGHT_PRESSED; break; case 'p': case 'P': momentary|=PAUSE_PRESSED; keys_down|=PAUSE_PRESSED; break; case SDLK_ESCAPE: momentary|=MENU_PRESSED; keys_down|=MENU_PRESSED; break; case SDLK_RIGHT: momentary|=RIGHT_PRESSED; keys_down|=RIGHT_PRESSED; break; case SDLK_LEFT: momentary|=LEFT_PRESSED; keys_down|=LEFT_PRESSED; break; case SDLK_UP: momentary|=UP_PRESSED; keys_down|=UP_PRESSED; break; case SDLK_DOWN: momentary|=DOWN_PRESSED; keys_down|=DOWN_PRESSED; break; default: *alphanum=keypressed; break; } } } return (momentary<<16)+keys_down; } static void LoadPinkTexture(int x,int y,int which_one,int transparent, int repeat_type) { static GLubyte *texture; int i; texture=calloc(64*64*4,sizeof(GLubyte)); for(i=0;i<64*64;i++) { texture[(i*4)+0]=0xff; texture[(i*4)+1]=0x44; texture[(i*4)+2]=0xfd; texture[(i*4)+3]=0xff; } glBindTexture(GL_TEXTURE_2D,textures[which_one]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeat_type); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeat_type); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0,GL_RGBA,GL_UNSIGNED_BYTE,texture); } static void reshape(int w,int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,(GLfloat)w/(GLfloat)h,1.0,100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //glTranslatef(0.0,0.0,-3.6); } static int generate_sphere(float radius, int latitudes, int longitudes, int texture) { /* The way I do this is brutally inefficient */ /* I should optimize it later [ie, do everything in radians] */ float delta_theta,delta_phi; float init_x1,init_y1,init_z1,x1,y1,z1; float init_x2,init_y2,init_z2,x2,y2,z2; int phi_prime,theta_prime; glBindTexture(GL_TEXTURE_2D,textures[texture]); delta_phi=180.0/(float)latitudes; delta_theta=360.0/(float)longitudes; for(phi_prime=0;phi_prime2.0*PI) camera_direction-=2.0*PI; camerax=10.0*sin(camera_direction); cameray=10.0*cos(camera_direction); rotation++; if (rotation>15) rotation-=16; printf("ROT=%d %.2lf\n",rotation,camera_direction); } if (keyspressed&UP_PRESSED) { cameraz+=0.5; } if (keyspressed&DOWN_PRESSED) { cameraz-=0.5; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(camerax,cameray,cameraz, 0.0,0.0,0.0, 0.0,0.0,1.0); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light); glLightfv(GL_LIGHT0, GL_SPECULAR,white_light); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); { GLfloat default_a[]={0.6,0.6,0.6,1.0}; GLfloat default_d[]={0.8,0.8,0.8,1.0}; GLfloat default_s[]={0.0,0.0,0.0,1.0}; GLfloat default_e[]={0.0,0.0,0.0,1.0}; glMaterialfv(GL_FRONT,GL_AMBIENT,default_a); glMaterialfv(GL_FRONT,GL_DIFFUSE,default_d); glMaterialfv(GL_FRONT,GL_SPECULAR,default_s); glMaterialfv(GL_FRONT,GL_EMISSION,default_e); } glBegin(GL_QUADS); glVertex3f(-5,-5,0); glVertex3f(5,-5,0); glVertex3f(5,5,0); glVertex3f(-5,5,0); glVertex3f(-5,5,0); glVertex3f(5,5,0); glVertex3f(5,5,5); glVertex3f(-5,5,5); glVertex3f(-5,-5,0); glVertex3f(-5,5,0); glVertex3f(-5,5,5); glVertex3f(-5,-5,5); glEnd(); glEnable(GL_TEXTURE_2D); glPushMatrix(); glTranslatef(0,0,6.5); glRotatef(90,0,1,0); glPushMatrix(); glRotatef(270,0,0,1); generate_sphere(2,20,20,TFV_PINK_TEXTURE); glPopMatrix(); glPopMatrix(); /* Flush it out to the device */ glFlush(); SDL_GL_SwapBuffers(); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); /* Emulate low frame-rates */ usleep(100000); } return 1; } static void LoadTextures(void) { #define _BSD_SOURCE 1 #if (BYTE_ORDER==BIG_ENDIAN) printf("We are big_endian\n"); glPixelStorei(GL_UNPACK_SWAP_BYTES,1); #endif glPixelStorei(GL_UNPACK_ALIGNMENT,1); glGenTextures(TOTAL_TEXTURES,textures); LoadPinkTexture(64,64,TFV_PINK_TEXTURE,0,GL_REPEAT); } static void init_gl(void) { #if (BYTE_ORDER==BIG_ENDIAN) glPixelStorei(GL_UNPACK_SWAP_BYTES,1); #endif glPixelStorei(GL_UNPACK_ALIGNMENT,1); glClearColor(0.0,0.0,0.0,0.0); glClearDepth(1.0); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glMatrixMode(GL_PROJECTION); glLoadIdentity(); LoadTextures(); } int main(int argc, char **argv) { int mode; int fullscreen=0; int xsize,ysize; xsize=640; ysize=480; /* Initialize SDL */ if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK)<0) { printf("Error trying to init SDL: %s\n",SDL_GetError()); return -1; } if (fullscreen) mode=SDL_OPENGL | SDL_FULLSCREEN; else mode=SDL_OPENGL; /* Create the OpenGL screen */ if ( SDL_SetVideoMode(xsize, ysize, 0, mode) == NULL ) { printf("Unable to create OpenGL screen: %s\n", SDL_GetError()); SDL_Quit(); return -2; } SDL_WM_SetCaption("Guinea Pig Adventure...",NULL); /* Setup OpenGL screen */ init_gl(); reshape(xsize,ysize); draw_pink_sphere(xsize,ysize); /* Quit */ SDL_Quit(); return 0; }