#define _GNU_SOURCE #include #include #include #include #ifdef HAVE_SDL #include #endif /* HAVE_SDL */ #include /* our default visual layer */ #include static struct visual_ops visual_ops = { .quit = NULL, .init = NULL, .update = NULL, .waitkey = NULL, .clear = NULL, .fill = NULL, .display = NULL, .save = NULL, }; void visual_change_layer( const struct visual_ops *layer_ops ) { assert( layer_ops != NULL ); assert( layer_ops->quit != NULL ); assert( layer_ops->init != NULL ); assert( layer_ops->update != NULL ); assert( layer_ops->waitkey != NULL ); assert( layer_ops->clear != NULL ); assert( layer_ops->fill != NULL ); assert( layer_ops->display != NULL ); assert( layer_ops->save != NULL ); visual_ops = *layer_ops; } #define CALL_RET_INT( op, args... ) \ do { if (visual_ops.op != NULL ) \ return visual_ops.op( args ); \ else err( "You should define a visual layer with " #op "() first.\n" );\ return -1; \ } while ( 0 ) #define CALL_RET_VOID( op, args... ) \ do { if (visual_ops.op != NULL ) \ visual_ops.op( args ); \ else err( "You should define a visual layer with " #op "() first.\n" );\ } while ( 0 ) /** * Quit engine. */ void visual_quit( void ) { CALL_RET_VOID( quit ); } /** * Initialize video device using the given dimensions. * * @param w screen width * @param h screen height * * @return 0 on succes, error otherwise. */ int visual_init( uint16_t w, uint16_t h ) { char *envopt = getenv( "VISUAL" ); if ( visual_ops.init == NULL ) { if ( envopt == NULL ) { #ifdef HAVE_SDL visual_change_layer_sdl(); /* sdl is our default visual layer */ #else visual_change_layer_ppm(); /* ppm is our default visual layer */ #endif } else { if ( strcasecmp( envopt, "ppm" ) == 0 ) visual_change_layer_ppm(); #ifdef HAVE_SDL else if ( strcasecmp( envopt, "sdl" ) == 0 ) visual_change_layer_sdl(); #endif else visual_change_layer_ppm(); } } CALL_RET_INT( init, w, h ); return 0; } /** * Update screen. * * @return 0 on success, error otherwise. */ int visual_update( void ) { CALL_RET_INT( update ); return 0; } /** * Wait for key and return key symbol as described in SDLKey(3). * * It also handle program exit and do screen refreshes when * required. * * @return key symbol or 0 on error. */ int visual_waitkey( void ) { CALL_RET_INT( waitkey ); return 0; } /** * Clear (blanks) screen. * * @return 0 on success, error otherwise. */ int visual_clear( void ) { CALL_RET_INT( clear ); return 0; } /** * Fill rectangular screen region with the given color. * * @param color what color to paint. * @param rectan * * @return 0 on success, error otherwise. */ int visual_fill( color_t color, rect_t rect ) { CALL_RET_INT( fill, color, rect ); return 0; } /** * Display the surface at the given position * * @param surface what to display * @param pos where to display * * @return 0 on success, error otherwise. */ int visual_display( surface_t *surface, coord_t pos ) { CALL_RET_INT( display, surface, pos ); return 0; } /** * Save the display to a bitmap image. * * @param filename where to save the file. * * @return 0 on success, error otherwise. */ int visual_save( const char *filename ) { CALL_RET_INT( save, filename ); return 0; }