%PDF- %PDF-
Direktori : /usr/share/doc/libvisual-0.4-0/examples/ |
Current File : //usr/share/doc/libvisual-0.4-0/examples/simplesdl.c |
#include <unistd.h> #include <stdlib.h> #include <string.h> #include <SDL.h> #include "../libvisual/libvisual.h" /* The code in this example is written a bit hacky, but the libvisual code is as it should * be used so you could take that and use that as an example */ SDL_Surface *screen; SDL_Color colors[256]; unsigned char *scrbuf; /* The visual plugin */ VisActor *actor; /* The video context, contains information about, depth, bpp, width, height, etc etc */ VisVideo *video; /* Palette data structure for 8 bits mode */ VisPalette *pal = NULL; /* The input plugin */ VisInput *input; /* The container */ VisBin *bin; int bpp = 1; int gl_plug = 0; void sdl_fullscreen_toggle (void); void sdl_fullscreen_xy (int *x, int *y); int sdl_fullscreen_set (int mode); void sdl_size_request (int width, int height); void sdl_init (int width, int height); void sdl_create (int width, int height); void sdl_draw_buf (void); void sdl_set_pal (void); /* Fullscreen stuff */ void sdl_fullscreen_toggle () { static int fullscreen = 0; fullscreen = 1 - fullscreen; sdl_fullscreen_set (fullscreen); } void sdl_fullscreen_xy (int *x, int *y) { SDL_Rect **modelist; int i; int width = screen->w; int height = screen->h; modelist = SDL_ListModes (NULL, SDL_FULLSCREEN); if (modelist == NULL) { *x = width; *y = height; } /* Is the window bigger than the highest available resolution ? */ if (modelist[0]->w <= width || modelist[0]->h <= height) { *x = modelist[0]->w; *y = modelist[0]->h; return; } for(i = 0; modelist[i]; ++i) { if (modelist[i]->w >= width && modelist[i]->h >= height) { *x = modelist[i]->w; *y = modelist[i]->h; } } } int sdl_fullscreen_set (int mode) { static int oldw; static int oldh; int screen_fullscreen = 0; int tempx; int tempy; switch (mode) { case 0: if ((screen->flags & SDL_FULLSCREEN) != 0) { SDL_WM_ToggleFullScreen (screen); SDL_ShowCursor (SDL_ENABLE); sdl_size_request (oldw, oldh); screen_fullscreen = 0; return 0; } break; case 1: if ((screen->flags & SDL_FULLSCREEN) == 0) { if (screen_fullscreen == 0) { oldw = screen->w; oldh = screen->h; } if (screen_fullscreen == 1) SDL_WM_ToggleFullScreen (screen); sdl_fullscreen_xy (&tempx, &tempy); sdl_size_request (tempx, tempy); if (SDL_WM_ToggleFullScreen (screen)) { SDL_ShowCursor (SDL_DISABLE); screen_fullscreen = 1; return 0; } else { sdl_size_request (oldw, oldh); screen_fullscreen = 0; return -1; } } break; default: break; } return 0; } /* Sdl stuff */ void sdl_size_request (int width, int height) { SDL_FreeSurface (screen); sdl_create (width, height); visual_video_set_dimension (video, width, height); /* Only needed if the framebuffer pitch is * differs from the width, (this happens * in SDL */ visual_video_set_pitch (video, screen->pitch); visual_actor_video_negotiate (actor, 0, FALSE, FALSE); if (gl_plug == 0) { free (scrbuf); scrbuf = malloc (visual_video_get_size (video)); memset (scrbuf, 0, visual_video_get_size (video)); visual_video_set_buffer (video, scrbuf); } } void sdl_init (int width, int height) { if (SDL_Init (SDL_INIT_VIDEO) < 0) { fprintf (stderr, "Unable to init SDL VIDEO: %s\n", SDL_GetError ()); exit (0); } sdl_create (width, height); } void sdl_create (int width, int height) { const SDL_VideoInfo *videoinfo; int videoflags; if (gl_plug == 1) { videoinfo = SDL_GetVideoInfo (); if (videoinfo == 0) { printf ("Couldn't get video info\n"); exit (-1); } videoflags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE | SDL_RESIZABLE; if (videoinfo->hw_available) videoflags |= SDL_HWSURFACE; else videoflags |= SDL_SWSURFACE; if (videoinfo->blit_hw) videoflags |= SDL_HWACCEL; SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); screen = SDL_SetVideoMode (width, height, 16, videoflags); } else screen = SDL_SetVideoMode (width, height, bpp * 8, SDL_RESIZABLE); } void sdl_draw_buf () { unsigned char *str = (unsigned char *) screen->pixels; memcpy (str, scrbuf, visual_video_get_size (video)); SDL_UpdateRect (screen, 0, 0, screen->w, screen->h); } void sdl_set_pal () { int i; for (i = 0; i < 256; i ++) { colors[i].r = pal->colors[i].r; colors[i].g = pal->colors[i].g; colors[i].b = pal->colors[i].b; } SDL_SetColors (screen, colors, 0, 256); } /* Main stuff */ int main (int argc, char *argv[]) { int width = 480, height = 360; int depth = VISUAL_VIDEO_DEPTH_8BIT; int freeze = 0; int depthflag = 0; time_t begin = time (NULL), end; int frames = 0; char *input_name = NULL; if (visual_init (&argc, &argv) < 0) visual_log (VISUAL_LOG_ERROR, "Could not initialize Libvisual"); /* Check libvisual version */ visual_log (VISUAL_LOG_INFO, "Libvisual version %s", visual_get_version ()); /* Make a new actor from actlist, with pluginname */ if (argc > 1) actor = visual_actor_new (argv[1]); else actor = visual_actor_new ("oinksie"); if (actor->plugin == NULL) { visual_log (VISUAL_LOG_ERROR, "Couldn't create actor plugin"); return -1; } depthflag = visual_actor_get_supported_depth (actor); if (argc > 2) { /* Get an enum value from the depth argument */ depth = visual_video_depth_enum_from_value (atoi (argv[2])); /* Check if the depth is supported */ if (visual_video_depth_is_supported (depthflag, depth) < 1) { visual_log (VISUAL_LOG_INFO, "Plugin doesn't support this depth, but we'll set up an transformation enviroment."); visual_log (VISUAL_LOG_INFO, "However showing you a nice list of supported depths anyway"); /* Show a list of supported depths */ int i, j; i = VISUAL_VIDEO_DEPTH_NONE; if (visual_video_depth_is_supported (depthflag, i) == 1) visual_log (VISUAL_LOG_INFO, "Support visual video context NONE"); do { j = i; i = visual_video_depth_get_next (depthflag, j); if (i == j) break; if (i == VISUAL_VIDEO_DEPTH_GL) { visual_log (VISUAL_LOG_INFO, "Support visual depth GL"); } else { visual_log (VISUAL_LOG_INFO, "Support visual depth %d", visual_video_depth_value_from_enum (i)); } } while (i < VISUAL_VIDEO_DEPTH_GL); depth = i; } } else { /* Get the highest supported depth */ depth = visual_video_depth_get_highest (depthflag); } /* When the plugin is an GL plugin */ if (depth == VISUAL_VIDEO_DEPTH_GL) gl_plug = 1; sdl_init (width, height); /* We need to init sdl first when we use GL, and then realize * and set dimensions, this is because the init and dimension * code within the gl plugin contains GL code. */ visual_actor_realize (actor); /* Create a new video context */ video = visual_video_new (); /* Link the video context to the actor */ visual_actor_set_video (actor, video); /* Set depth, 16BIT, 24BIT, 32BIT, GL do also exist */ visual_video_set_depth (video, depth); /* Set dimension */ visual_video_set_dimension (video, width, height); /* Negotiate with video, if needed, the actor will set up and enviroment * for depth transformation and it does all the size negotation stuff */ if (visual_actor_video_negotiate (actor, 0, FALSE, FALSE) == -1) visual_log (VISUAL_LOG_ERROR, "Couldn't negotiate the actor with the video"); if (gl_plug == 0) { /* Retrieve the bpp from the depth so we can use that for buffer * allocating and SDL init */ bpp = visual_video_bpp_from_depth (depth); /* Now we know the size, allocate the buffer */ scrbuf = malloc (visual_video_get_size (video)); memset (scrbuf, 0, visual_video_get_size (video)); /* Link the buffer to the video context */ visual_video_set_buffer (video, scrbuf); } if (argc >= 4) input_name = argv[3]; else input_name = "alsa"; input = visual_input_new (input_name); visual_log_return_val_if_fail(input != NULL, -1 ); if (input == NULL) { visual_log(VISUAL_LOG_ERROR, "Plugin \"%s\" doesn't exist or could not be loaded.\n", input_name); return -1; } /* Create a new bin, a bin is a container for easy * management of an working input, actor, render, output pipeline */ bin = visual_bin_new (); /* Add the actor, input, video to the bin */ visual_bin_connect (bin, actor, input); visual_bin_realize (bin); SDL_Event event; /* This kinda sucks, that we have to size twice, but this is needed for the GL plugins, we need * to init sdl gl stuff before initting the plugin, because the plugin sets GL opts */ sdl_create (video->width, video->height); while (1) { if (freeze == 0) { /* Run the bin, this will retrieve sound * analyse the sound, push it towards the * actor plugin, render and return */ visual_bin_run (bin); if (gl_plug == 1) { SDL_GL_SwapBuffers (); } else { /* Retrieve palette information */ pal = visual_bin_get_palette (bin); if (pal != NULL) sdl_set_pal (); sdl_draw_buf (); } frames++; } usleep (5000); while (SDL_PollEvent (&event)) { VisEventQueue *vevent; vevent = visual_plugin_get_eventqueue (visual_actor_get_plugin (visual_bin_get_actor (bin))); switch (event.type) { case SDL_KEYUP: visual_event_queue_add_keyboard (vevent, event.key.keysym.sym, event.key.keysym.mod, VISUAL_KEY_UP); break; case SDL_KEYDOWN: visual_event_queue_add_keyboard (vevent, event.key.keysym.sym, event.key.keysym.mod, VISUAL_KEY_DOWN); switch (event.key.keysym.sym) { case SDLK_F11: sdl_fullscreen_toggle (); break; case SDLK_f: freeze = 1 - freeze; break; case SDLK_ESCAPE: goto out; break; default: /* to avoid warnings */ break; } break; case SDL_VIDEORESIZE: sdl_size_request (event.resize.w, event.resize.h); break; case SDL_QUIT: goto out; break; default: /* to avoid warnings */ break; } } } out: SDL_Quit (); end = time (NULL); visual_log (VISUAL_LOG_INFO, "Drawn %d frames in %d seconds, average fps %d", (int)frames, (int)(end - begin), (end - begin) == 0 ? (int)frames : (int)(frames / (end - begin))); visual_video_free_buffer (video); visual_quit (); return 0; }