#include #include //#include #ifndef USE_SDL #include #else #include #include #include #endif //#ifndef _WIN32 // #include // us time measure // #include //#else // #include // us time measure //#endif #include "sys_stuff.h" #ifndef USE_SDL /* use glut */ static int keymodif = 0 ; static int fullscreen = 0 ; static void update_key_modifiers(void) { int m; m=glutGetModifiers(); keymodif=0 ; if (m & GLUT_ACTIVE_SHIFT) keymodif |= KEY_MODIFIER_SHIFT ; if (m & GLUT_ACTIVE_CTRL) keymodif |= KEY_MODIFIER_CTRL ; if (m & GLUT_ACTIVE_ALT) keymodif |= KEY_MODIFIER_ALT ; } static void handle_mouse_motion(int x, int y) { MouseMotion(x,y,keymodif); } static void handle_key_event(unsigned char key, int x, int y) { update_key_modifiers(); Key( ((int)key)&0xFF, keymodif ) ; } static void handle_display_event(void) { DisplayFunc() ; glutSwapBuffers(); } static void handle_special_key_event(int key, int x, int y ) { int keysym=0 ; update_key_modifiers(); switch (key) { case GLUT_KEY_PAGE_UP: keysym = KSYM_PAGE_UP ; break; case GLUT_KEY_UP: keysym = KSYM_UP ; break; case GLUT_KEY_PAGE_DOWN: keysym = KSYM_PAGE_DOWN ; break; case GLUT_KEY_DOWN: keysym = KSYM_DOWN ; break; case GLUT_KEY_LEFT: keysym = KSYM_LEFT ; break; case GLUT_KEY_RIGHT: keysym = KSYM_RIGHT ; break; case GLUT_KEY_F1: keysym = KSYM_F1 ; break; case GLUT_KEY_F2: keysym = KSYM_F2 ; break; case GLUT_KEY_F3: keysym = KSYM_F3 ; break; case GLUT_KEY_F4: keysym = KSYM_F4 ; break; default: return ; } Key(keysym,keymodif) ; } static void handle_mouse_event(int button,int state, int x, int y) { MouseButtonEnum b ; MouseButtonState s ; /* Process first the key modifiers */ update_key_modifiers(); /* then the mouse buttons */ switch(button) { case GLUT_LEFT_BUTTON: b = MOUSE_LEFT_BUTTON; break ; case GLUT_RIGHT_BUTTON: b = MOUSE_RIGHT_BUTTON; break ; case GLUT_MIDDLE_BUTTON: b = MOUSE_MIDDLE_BUTTON; break ; case 3: b = MOUSE_WHEEL_UP_BUTTON; break ; case 4: b = MOUSE_WHEEL_DOWN_BUTTON; break ; default: /* Unknown button: ignore */ return ; } s=-1; if( state==GLUT_DOWN ) s = MOUSE_DOWN; if( state==GLUT_UP ) s = MOUSE_UP; // s = (state==GLUT_DOWN)?MOUSE_DOWN:MOUSE_UP ; MouseEvent(b,s,x,y,keymodif) ; } void sys_resize( int width, int height ) { glutReshapeWindow(width,height); ResizeWindow(width,height) ; } static void handle_reshape_event( int width, int height ) { ResizeWindow(width,height) ; } void (*timer_cb)(void) = NULL ; static void timer_callback(int v) { if (timer_cb!=NULL) { timer_cb() ; } } /* ============================ */ void sys_create_display(int *argc, char **argv, int width,int height) { // glutInitWindowPosition(0, 0); glutInitWindowSize(width,height); glutInit(argc, argv ); glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); glutCreateWindow( argv[0] ); // glutFullScreen(); } int sys_get_fullscreen(void) { return fullscreen; } void sys_fullscreen( int fullscr, int width, int height ) { fullscreen=fullscr; if(fullscreen){ glutFullScreen(); } else { sys_resize(1024,768) ; } } void sys_toggle_fullscreen( int width, int height ) { if (fullscreen){ sys_fullscreen( 0, width, height ); } else { sys_fullscreen( 1, width, height ); } } void sys_redisplay(void) { glutPostRedisplay(); } void sys_exit(int code) { exit(code) ; } void sys_set_timer(int ms,void (*cb)(void)) { timer_cb = cb ; if (cb!=NULL) { glutTimerFunc(ms,timer_callback,0); } } sysResolution * sys_list_modes( void ) { sysResolution * sysmodes; sysmodes = (sysResolution *) malloc(1*sizeof(sysResolution)); sysmodes[0].w=0; /* terminator */ sysmodes[0].h=0; /* terminator */ return sysmodes; } void sys_main_loop(void) { glutReshapeFunc ( handle_reshape_event ); glutKeyboardFunc ( handle_key_event ); glutSpecialFunc ( handle_special_key_event ); glutDisplayFunc ( handle_display_event ); glutMouseFunc ( handle_mouse_event ); glutMotionFunc ( handle_mouse_motion ); glutPassiveMotionFunc( handle_mouse_motion ); glutMainLoop(); } #else /* use SDL */ static int fullscreen = 0 ; static int keymodif =0 ; static int vidmode_bpp=0 ; static int sdl_on = 0 ; static SDL_Surface * vid_surface = NULL; void sys_exit( int code ) { if (sdl_on) { /* * Quit SDL so we can release the fullscreen * mode and restore the previous video settings, * etc. */ SDL_Quit( ); } /* Exit program. */ exit( code ); } /* ========================================= */ void sys_create_display(int *argc, char **argv, int width,int height) { /* Information about the current video settings. */ const SDL_VideoInfo* info = NULL; int vidmode_flags=0 ; vid_surface = SDL_GetVideoSurface(); /* First, initialize SDL's video subsystem. */ if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { fprintf( stderr, "Video initialization failed: %s\n", SDL_GetError( ) ); sys_exit(1); } atexit(SDL_Quit); sdl_on = 1 ; /* Let's get some video information. */ info = SDL_GetVideoInfo( ); if( !info ) { /* This should probably never happen. */ fprintf( stderr, "Video query failed: %s\n", SDL_GetError( ) ); sys_exit(1); } vidmode_bpp = info->vfmt->BitsPerPixel; /* * Now, we want to setup our requested * window attributes for our OpenGL window. * We want *at least* 5 bits of red, green * and blue. We also want at least a 16-bit * depth buffer. * * The last thing we do is request a double * buffered window. '1' turns on double * buffering, '0' turns it off. * * Note that we do not use SDL_DOUBLEBUF in * the flags to SDL_SetVideoMode. That does * not affect the GL attribute state, only * the standard 2D blitting setup. */ SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); /* it could be wise to change the default key timing */ SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); // SDL_EnableKeyRepeat( 0, SDL_DEFAULT_REPEAT_INTERVAL ); /* key repeat causaed problem when toggling fullscreen !!! */ /* * We want to request that SDL provide us * with an OpenGL window, in a fullscreen * video mode. */ vidmode_flags = SDL_OPENGL; if (fullscreen) { vidmode_flags |= SDL_FULLSCREEN; }else{ vidmode_flags |= SDL_RESIZABLE; } if( SDL_SetVideoMode( width, height, vidmode_bpp, vidmode_flags ) == 0 ) { fprintf( stderr, "Video mode set failed: %s\n", SDL_GetError( ) ); sys_exit( 1 ); } } int sys_get_fullscreen(void) { return fullscreen; } void sys_fullscreen( int fullscr, int width, int height ) { SDL_Surface * screen; fullscreen = fullscr; screen = SDL_GetVideoSurface(); if ( fullscreen!=0 && (screen->flags & SDL_FULLSCREEN)==0 ){ SDL_WM_ToggleFullScreen(screen); } else if( fullscreen==0 && (screen->flags & SDL_FULLSCREEN)!=0 ){ SDL_WM_ToggleFullScreen(screen); } /* if (fullscreen) { vidmode_flags |= SDL_FULLSCREEN; vidmode_flags &= (~SDL_RESIZABLE); } else { vidmode_flags &= (~SDL_FULLSCREEN); vidmode_flags |= SDL_RESIZABLE; } SDL_SetVideoMode( width, height, vidmode_bpp, vidmode_flags ); */ } void sys_toggle_fullscreen( int width, int height ) { /* SDL_Surface *screen = SDL_GetVideoSurface(); SDL_WM_ToggleFullScreen(screen); fullscreen = (fullscreen==0)?1:0;*/ if (fullscreen){ sys_fullscreen( 0, width, height ); } else { sys_fullscreen( 1, width, height ); } } void sys_redisplay(void) { } void (*timer_cb)(void) = NULL ; void sys_set_timer(int ms,void (*cb)(void)) { timer_cb = cb ; } static void update_key_modifiers(void) { SDLMod m ; m=SDL_GetModState(); keymodif=0 ; if (KMOD_CTRL & m) keymodif |= KEY_MODIFIER_CTRL ; if (KMOD_SHIFT & m) keymodif |= KEY_MODIFIER_SHIFT ; if (KMOD_ALT & m) keymodif |= KEY_MODIFIER_ALT ; } static void handle_button_event(SDL_MouseButtonEvent *e) { MouseButtonEnum b ; MouseButtonState s ; update_key_modifiers() ; /* then the mouse buttons */ switch(e->button) { case SDL_BUTTON_LEFT: b = MOUSE_LEFT_BUTTON; break ; case SDL_BUTTON_RIGHT: b = MOUSE_RIGHT_BUTTON; break ; case SDL_BUTTON_MIDDLE: b = MOUSE_MIDDLE_BUTTON; break ; case 4: b = MOUSE_WHEEL_UP_BUTTON; break ; case 5: b = MOUSE_WHEEL_DOWN_BUTTON; break ; default: /* Unknown button: ignore */ return ; } s = -1; if(e->state==SDL_PRESSED) s=MOUSE_DOWN; if(e->state==SDL_RELEASED) s=MOUSE_UP; // s = (e->state==SDL_PRESSED)?MOUSE_DOWN:MOUSE_UP ; MouseEvent(b,s,e->x,e->y,keymodif) ; } static int translate_key(SDL_KeyboardEvent* e) { int keysym=0; switch (e->keysym.sym) { case SDLK_PAGEUP: keysym = KSYM_PAGE_UP ; break; case SDLK_UP: keysym = KSYM_UP ; break; case SDLK_PAGEDOWN: keysym = KSYM_PAGE_DOWN ; break; case SDLK_DOWN: keysym = KSYM_DOWN ; break; case SDLK_LEFT: keysym = KSYM_LEFT ; break; case SDLK_RIGHT: keysym = KSYM_RIGHT ; break; case SDLK_F1: keysym = KSYM_F1 ; break; case SDLK_F2: keysym = KSYM_F2 ; break; case SDLK_F3: keysym = KSYM_F3 ; break; case SDLK_F4: keysym = KSYM_F4 ; break; case SDLK_KP_ENTER: keysym = KSYM_KP_ENTER ; break; default: if (e->keysym.sym>0 && e->keysym.sym<=127) { keysym = (int) e->keysym.sym ; } else { /* ignore */ return -1; } } return keysym; } static void handle_key_down(SDL_KeyboardEvent* e) { int keysym; update_key_modifiers(); keysym = translate_key(e); if(keysym!=-1){ Key(keysym, keymodif); } } static void handle_key_up(SDL_KeyboardEvent* e) { int keysym; update_key_modifiers(); keysym = translate_key(e); if(keysym!=-1){ KeyUp(keysym, keymodif); } } void sys_resize( int width, int height ) { SDL_Surface * screen; screen = SDL_GetVideoSurface(); SDL_EnableKeyRepeat( 0, 0 ); SDL_SetVideoMode( width, height, screen->format->BitsPerPixel, screen->flags ); SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); ResizeWindow(width,height) ; } static void handle_reshape_event( int width, int height ) { sys_resize( width, height ); } void handle_motion_event(SDL_MouseMotionEvent *e) { update_key_modifiers() ; MouseMotion(e->x,e->y,keymodif); } static void process_events( void ) { /* Our SDL event placeholder. */ SDL_Event event; /* Grab all the events off the queue. */ while( SDL_PollEvent( &event ) ) { switch( event.type ) { case SDL_KEYUP: handle_key_up( &event.key ); break; case SDL_KEYDOWN: /* Handle key presses. */ handle_key_down( &event.key ); break; case SDL_QUIT: /* Handle quit requests (like Ctrl-c). */ sys_exit(0); break; case SDL_MOUSEMOTION: handle_motion_event(&(event.motion)) ; break ; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: handle_button_event(&(event.button)) ; break ; case SDL_VIDEORESIZE: handle_reshape_event(event.resize.w,event.resize.h); break; default: // printf( "EVENT: %d\n", (int) event.type ) ; break; } } } sysResolution * sys_list_modes( void ) { sysResolution * sysmodes; SDL_Rect ** modes; int i, modenr; modes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE); for(i=0;modes[i];i++); modenr=i; sysmodes = (sysResolution *) malloc((modenr+1)*sizeof(sysResolution)); for(i=0;modes[i];i++){ sysmodes[i].w = modes[i]->w; sysmodes[i].h = modes[i]->h; } sysmodes[i].w=0; /* terminator */ sysmodes[i].h=0; /* terminator */ return( sysmodes ); } void sys_main_loop(void) { while(1) { process_events() ; DisplayFunc() ; SDL_GL_SwapBuffers( ); if (timer_cb!=NULL) { timer_cb(); } SDL_Delay(10); } } #endif